﻿#region

using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;
using WindowsAPI.Service;
using WindowsAPI.Windows;

#endregion

namespace WindowsAPI
{
    [SuppressUnmanagedCodeSecurity, Dll(FileName)]
    public static partial class User32
    {
        /* ------------------------------------------------------------------------------------------ */

        public const string FileName = "User32.dll";

        /* ------------------------------------------------------------------------------------------ */

        /// <summary>Функция отображает или скрывает курсор</summary>
        /// <param name="bShow">
        /// Определяет, инкрементируется или декрементируется внутренний счетчик отображения. 
        /// Если значение bShow равно TRUE - внутренний счетчик отображения увеличивается на единицу. 
        /// Если значение bShow равно FALSE - внутренний счетчик отображения уменьшается на единицу
        /// </param>
        /// <returns>Возвращаемое значение определяет новый счетчик отображения</returns>
        /// <remarks>
        /// Функция устанавливает внутренний счетчик, определяющий, должен ли быть отображен курсор. 
        /// Курсор отображается лишь в том случае, если счетчик отображения больше нуля или равен нулю. 
        /// Если в системе установлена мышь, то начальное значение счетчика равно 0. 
        /// Если мышь в системе не установлена, начальное значение счетчика равно -1
        /// </remarks>
        [DllImport(FileName)]
        public static extern int ShowCursor(bool bShow);

        /// <summary>Sets the input locale identifier (formerly called the keyboard layout handle) for the calling thread or the current process. The input locale identifier specifies a locale as well as the physical layout of the keyboard</summary>
        /// <param name="hkl">Input locale identifier to be activated.</param>
        /// <param name="Flags">Specifies how the input locale identifier is to be activated.</param>
        /// <returns>The return value is of type HKL. If the function succeeds, the return value is the previous input locale identifier. Otherwise, it is zero</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern HKL ActivateKeyboardLayout(HKL hkl, KLF Flags);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool GetKeyboardLayoutName([Out] StringBuilder pwszKLID);

        [DllImport(FileName)]
        public static extern HKL LoadKeyboardLayout(string pwszKLID, KLF Flags);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool UnloadKeyboardLayout(HKL hkl);

        [DllImport(FileName, CharSet = CharSet.Auto)]
        public static extern uint GetDoubleClickTime();

        [DllImport(FileName, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern bool SetDoubleClickTime(uint uInterval);

        #region SystemParametersInfo

        //Error: шаблон-функция для pInvoke
        //[DllImport(FileName, SetLastError = true)]
        //[return: MarshalAs(UnmanagedType.Bool)]
        //public static extern bool SystemParametersInfo<T>(SPI uiAction, uint uiParam, ref T pvParam, SPIF fWinIni); // T = any type

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, IntPtr pvParam, SPIF fWinIni);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, string pvParam, SPIF fWinIni);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, StringBuilder pvParam, SPIF fWinIni);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, ref ANIMATIONINFO pvParam, SPIF fWinIni);
        #endregion

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr CreatePopupMenu();

        [DllImport(FileName, SetLastError = true)]
        public static extern bool InsertMenuItem(IntPtr hMenu, uint uItem, bool fByPosition, [In] ref MENUITEMINFO lpmii);

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetMessageExtraInfo();

        [DllImport(FileName, SetLastError = true, CharSet = CharSet.Auto)]
        public static extern bool DestroyIcon(IntPtr IconHandle);

        [DllImport(FileName, SetLastError = true, CharSet = CharSet.Auto, EntryPoint = "mouse_event")]
        public static extern void Mouse_Event(Mouse.API.MouseEventFlags Flags, uint dx, uint dy,
                                              Mouse.API.MouseEventDataXButtons Data, UIntPtr Extrainfo);

        [DllImport(FileName, SetLastError = true, CharSet = CharSet.Auto, EntryPoint = "keybd_event")]
        public static extern void Keybd_Event(byte vk, byte Scan, uint Flags, UIntPtr ExtraInfo);

        /// <summary>Функция синтезирует нажатия клавиши, движения  и щелчки кнопкой мыши</summary>
        /// <param name="InputCount">Устанавливает число структур в массиве <paramref name="Inputs"/></param>
        /// <param name="Inputs">
        /// Массив структур INPUT. 
        /// Каждая структура обозначает событие, которое будет вставлено во входной  поток клавиатуры или мыши
        /// </param>
        /// <param name="Size">
        /// Устанавливает размер, в байтах, структуры <see cref="Input"/>. 
        /// Если параметр <paramref name="Inputs"/> - не размер структуры INPUT, функция завершится ошибкой
        /// </param>
        /// <returns>
        /// Функция возвращает число событий, которые она успешно вставило во входной поток мыши или клавиатуры. Если функция возвращает нуль, ввод данных был уже блокирован другим потоком.
        /// Чтобы получить дополнительные сведения об ошибке, вызовите функцию <see cref="Marshal.GetLastWin32Error"/>
        /// </returns>
        [DllImport(FileName, SetLastError = true, CharSet = CharSet.Auto)]
        public static extern uint SendInput(uint InputCount, [MarshalAs(UnmanagedType.LPArray), In] Input[] Inputs, int Size);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool SetCursorPos(int X, int Y);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetCursorPos(out POINT Point);

        [DllImport(FileName, SetLastError = true)]
        public static extern short VkKeyScan(char ch);

        [DllImport(FileName, SetLastError = true)]
        public static extern short VkKeyScanEx(char ch, IntPtr hkl);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool SwapMouseButton(bool fSwap);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy,
                                               SetWindowPosFlags uFlags);

        /// <summary>
        /// Функция заменяет атрибуты указанного окна.
        /// Функция также устанавливает и 32-разрядное (long) значение при заданном смещении в дополнительную память окна.
        /// </summary>
        /// <param name="hWnd">Дескриптор окна и, косвенно, класс в которому принадлежит окно.</param>
        /// <param name="Index">
        /// Определяет отсчитываемое от нуля смещение устанавливаемого значения. 
        /// Допустимые значения находятся в диапазоне от нуля до число байтов дополнительной памяти окна, 
        /// минус размер целого числа. Чтобы установить любое другое значение, 
        /// задайте одну из ниже перечисленных величин.</param>
        /// <param name="NewLong">Устанавливает заменяемое значение.</param>
        /// <returns>
        /// Если функция завершается успешно, возвращаемое значение - предыдущая величина указанного 32-разрядного целого числа.
        /// Если функция завершается ошибкой, возвращаемое значение равняется нулю. 
        /// Чтобы получить дополнительную информацию об ошибке, вызовите GetLastError.
        /// Если предыдущее значение указанного 32-разрядного целого числа равняется нулю и функция завершается успешно, 
        /// возвращаемое значение равняется нулю, но функция не сбрасывает последнюю информацию об ошибке. 
        /// Это мешает выяснить, что это - успешное завершение или сбой. Чтобы разобраться с этим, 
        /// вам следует очистить последнюю информацию об ошибке при помощи вызова функции  SetLastError (0) 
        /// перед вызовом SetWindowLong. Тогда, сбой функции будет обозначен возвращаемым значением нуля и 
        /// результатом GetLastError, что это не нуль.
        /// </returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern long SetWindowLong(IntPtr hWnd, int Index, long NewLong);

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr SetWindowLongPtr(IntPtr hWnd, int Index, IntPtr NewLong);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ExitWindowsEx(ExitWindowsFlags Flags,
                                                ShutdownReason Reason = ShutdownReason.MajorOther);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool LockWorkStation();

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool RegisterHotKey(IntPtr hWnd, int id, int fsModifiers, int vk);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        /// <summary>Ищет дисплейный контекст окна</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Дескриптор графического контекста окна</returns>
        [DllImport(FileName, ExactSpelling = true, SetLastError = true)]
        public static extern IntPtr GetDC(IntPtr hWnd);

        [DllImport(FileName, ExactSpelling = true)]
        public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDC);

        [DllImport(FileName, ExactSpelling = true, SetLastError = true)]
        public static extern bool UpdateLayeredWindow(
                    IntPtr hWnd,
                    IntPtr hdcDst,
                    ref Point pptDst,
                    ref Size psize,
                    IntPtr hdcSrc,
                    ref Point pptSrc,
                    uint crKey,
                    [In] ref BlendFunction pblend,
                    uint dwFlags);

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetWindow(IntPtr hWnd, GW uCmd);

        /// <summary>Sets the show state and the restored, minimized, and maximized positions of the specified window.</summary>
        /// <param name="hWnd">A handle to the window.</param>
        /// <param name="lpwndpl">A pointer to a WINDOWPLACEMENT structure that specifies the new show state and window positions.
        /// <para>
        /// Before calling SetWindowPlacement, set the length member of the WINDOWPLACEMENT structure to sizeof(WINDOWPLACEMENT). SetWindowPlacement fails if the length member is not set correctly.
        /// </para>
        /// </param>
        /// <returns>
        /// If the function succeeds, the return value is nonzero.
        /// <para>If the function fails, the return value is zero. To get extended error information, call GetLastError.</para>
        /// </returns>                      
        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetWindowPlacement(IntPtr hWnd, [In] ref WINDOWPLACEMENT lpwndpl);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool ShowWindow(IntPtr hWnd, ShowWindowCommands nCmdShow);

        [DllImport(FileName, SetLastError = false)]
        public static extern IntPtr GetDesktopWindow();

        /// <summary>Идентификатор окна в фокусе ввода</summary>
        /// <returns>Дескриптор окна, которое получает ввод информации с клавиатуры</returns>
        [DllImport(FileName, CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr GetFocus();

        /// <summary>Назначает фокус ввода окну, напpавляя в него ввесь ввод с клавиатуpы</summary>
        /// <param name="hWnd">
        /// Дескриптор окна, которое примет ввод информации с клавиатуры. 
        /// Если этот параметр - ПУСТО (NULL), нажатия клавиши игнорируются
        /// </param>
        /// <returns>
        /// Если функция завершается успешно, величина возвращаемого значения - дескриптор окна, 
        /// которое до этого имело фокус клавиатуры. 
        /// Если параметр hWnd недопустимый или окно не связано с очередью сообщений вызывающего потока, 
        /// величина возвращаемого значения - ПУСТО (NULL). Чтобы получить дополнительные сведения об ошибке, 
        /// вызовите функцию GetLastError
        /// </returns>
        [DllImport(FileName, CharSet = CharSet.Auto, ExactSpelling = true)]
        public static extern IntPtr SetFocus(IntPtr hWnd);

        [DllImport(FileName, CharSet = CharSet.Auto)]
        public static extern bool PostMessage(IntPtr hWnd, int Msg, char wParam, int lParam);

        /// <summary>
        /// Функция AttachThreadInput подключает или отключает механизм обработки ввода данных одного из потоков к механизму другого потока
        /// </summary>
        /// <param name="dwCurrentThreadID">Идентификатор потока, который подключается</param>
        /// <param name="dwRemoteThreadId">Идентификатор потока, к которому подключаются</param>
        /// <param name="fAttach">Истина - подключить, ложь - отключить</param>
        /// <returns>Истина, если функция завершилась без ошибки</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool AttachThreadInput(int dwCurrentThreadID, int dwRemoteThreadId, bool fAttach);

        /// <summary>Функция извлекает дескриптор органа управления в заданном диалоговом окне</summary>
        /// <param name="hDlg">Дескриптор диалогового окна, которое содержит орган управления</param>
        /// <param name="nIDDlgItem">Устанавливает идентификатор извлекаемого органа управления</param>
        /// <returns>Если функция завершается успешно, возвращаемое значение - дескриптор окна указанного органа управления</returns>
        [DllImport(FileName, SetLastError = false)]
        public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);

        [DllImport(FileName, SetLastError = true)]
        internal static extern bool GetClientRect(IntPtr hWnd, ref RECT lpRect);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnableWindow(IntPtr hWnd, bool bEnable);

        /// <summary>Найти окно</summary>
        /// <param name="lpClassName">Имя класса</param>
        /// <param name="lpWindowName">Заголовок</param>
        /// <returns>Дескриптор найденого окна</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

        /// <summary>Найти окно</summary>
        /// <param name="hWndParent">Дескриптор окна предка</param>
        /// <param name="hwndChildAfter">Дескриптор предыдущего дочернего окна</param>
        /// <param name="lpszClass">Класс окна</param>
        /// <param name="lpszWindow">Заголовок окна</param>
        /// <returns>Дескриптор найденого окна</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr FindWindowEx(HandleRef hWndParent, HandleRef hwndChildAfter,
                                                 string lpszClass, string lpszWindow);

        /// <summary>Найти окно</summary>
        /// <param name="hWndParent">Дескриптор окна-предка</param>
        /// <param name="ChildAfter">Предыдущее дочернее окно</param>
        /// <param name="ClassName">Имя класса</param>
        /// <param name="WindowTitle">Заголовок</param>
        /// <returns>Дескриптор найденного окна</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr FindWindowEx(HandleRef hWndParent, HandleRef ChildAfter,
                                                 string ClassName, IntPtr WindowTitle);

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr WindowFromPoint(Point Point);

        [DllImport(FileName, SetLastError = true)]
        public static extern int EnumWindows(EnumWindowProc hWnd, IntPtr lParam);

        /// <summary>Свернуть окно</summary>
        /// <param name="hWnd">Дискриптор окна</param>
        /// <returns>Истина, если окно удалось свернуть</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool CloseWindow(HandleRef hWnd);

        /// <summary>Свернуть окно</summary>
        /// <param name="hWnd">Дискриптор окна</param>
        /// <returns>Истина, если окно удалось свернуть</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool CloseWindow(IntPtr hWnd);

        /// <summary>Уничтожить окно</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Истина, если окно уничтожено</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool DestroyWindow(HandleRef hWnd);

        /// <summary>Уничтожить окно</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Истина, если окно уничтожено</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool DestroyWindow(IntPtr hWnd);

        /// <summary>Установить окно по верх остальных</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Истина, если удалось установить окно поверх остальных</returns>
        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(HandleRef hWnd);

        /// <summary>Установить окно по верх остальных</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Истина, если удалось установить окно поверх остальных</returns>
        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetForegroundWindow(IntPtr hWnd);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool LockSetForegroundWindow(LSFW uLockCode);

        /// <summary>Получить дескриптор верхнего окна</summary>
        /// <returns>Дескриптор верхнего окна</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetForegroundWindow();

        [DllImport(FileName, SetLastError = true)]
        public static extern bool BringWindowToTop(IntPtr hWnd);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool BringWindowToTop(HandleRef hWnd);

        /// <summary>
        /// Если функция завершается успешно, величина возвращаемого 
        /// значения - дескриптор активного окна, связанного с потоком, 
        /// который вызывает функцию. Если вызывающий поток не имеет активного 
        /// окна, величина возвращаемого значения - ПУСТО
        /// </summary>
        /// <returns>Дескриптор окна</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetActiveWindow();

        /// <summary>Получить текст окна</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="lpString">Текст</param>
        /// <param name="nMaxCount">Число символов</param>
        /// <returns>Текст окна</returns>
        [DllImport(FileName, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int GetWindowText(HandleRef hWnd, StringBuilder lpString, uint nMaxCount);

        /// <summary>Получить текст окна</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="lpString">Текст</param>
        /// <param name="nMaxCount">Число символов</param>
        /// <returns>Текст окна</returns>
        [DllImport(FileName, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, uint nMaxCount);

        /// <summary>Число символов текста окна</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Число символов текста окна</returns>
        [DllImport(FileName, SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetWindowTextLength(HandleRef hWnd);

        /// <summary>Число символов текста окна</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Число символов текста окна</returns>
        [DllImport(FileName, SetLastError = true, CharSet = CharSet.Auto)]
        public static extern int GetWindowTextLength(IntPtr hWnd);

        /// <summary>Установить текст окна</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="lpString">Текст окна</param>
        /// <returns>Истина, если удалось</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool SetWindowText(HandleRef hWnd, string lpString);

        /// <summary>Установить текст окна</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="lpString">ТЕкст окна</param>
        /// <returns>Истина, если удалось</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool SetWindowText(IntPtr hWnd, string lpString);

        [DllImport(FileName, CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount);

        /// <summary>
        /// Функция возвращает обратно идентификатор потока, который создал определяемое окно, 
        /// но необязательно идентификатор процесса, который создал это окно
        /// </summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="lpdwProcessId">Адрес переменной для идентификатора процесса</param>
        /// <returns>Идентификатор потока, который создал окно</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern int GetWindowThreadProcessId(IntPtr hWnd, out int lpdwProcessId);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool EnumChildWindows(IntPtr hWmd, EnumWindowProc callback, IntPtr lParam);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetWindowPos(IntPtr hWnd, InsertAfterEnum InsertAfter,
                                               int x, int y, int cx, int cy, SetWindowPosFlags uFlags);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter,
                                               int X, int Y, int cx, int cy, uint uFlags);

        /// <summary>
        /// Функция MoveWindow изменяет позицию и габариты определяемого окна. Для окна верх-него уровня, позиция и 
        /// габариты - относительно левого верхнего угла экрана. Для дочернего окна, они - относительно левого верхнего 
        /// угла рабочей области родительского окна.
        /// </summary>
        /// <param name="hWnd">Идентификатор окна</param>
        /// <param name="X">Положение левого верхнего угла окна по оси X</param>
        /// <param name="Y">Положение левого верхнего угла окна по оси Y</param>
        /// <param name="nWidth">Ширина окна</param>
        /// <param name="nHeight">Высота окна</param>
        /// <param name="bRepaint">Определяет, должно ли окно быть перекрашено. Если этот параметр - ИСТИНА (TRUE), 
        /// окно принимает сообщение WM_PAINT. Если параметр - ЛОЖЬ(FALSE), никакого перекрашивания какого-либо сорта 
        /// не происходит. Это применяется к рабочей области, нерабочей области (включая строку заголовка и линейки 
        /// прокрутки) и любой части родительского окна, раскрытого в результате перемещения дочернего окна. 
        /// Если этот параметр - ЛОЖЬ(FALSE), прикладная программа должна явно аннулировать или перерисовать любые 
        /// части окна и родительского окна, которые нуждаются в перерисовке.</param>
        /// <returns>Если функция завершилась успешно, возвращается значение отличное от нуля. Если функция потерпела 
        /// неудачу, возвращаемое значение - ноль</returns>
        /// <remarks>Если параметр bRepaint - ИСТИНА (TRUE), Windows посылает сообщение WM_PAINT оконной процедуре 
        /// немедленно после перемещения окна (то есть функция MoveWindow вызывает функцию UpdateWindow). 
        /// Если bRepaint - ЛОЖЬ(FALSE), Windows помещает сообщение WM_PAINT в очередь сообщений, связанную с окном. 
        /// Цикл сообщений посылает сообщение WM_PAINT только после диспетчеризации всех других сообщений в очереди. 
        /// Функция MoveWindow посылает в окно сообщения WM_WINDOWPOSCHANGING, WM_WINDOWPOSCHANGED, 
        /// WM_MOVE, WM_SIZE и WM_NCCALCSIZE.</remarks>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetWindowDC(IntPtr hWnd);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool IsWindowEnabled(IntPtr hWnd);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, uint crKey,
                                                             byte bAlpha, uint dwFlags);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool SetLayeredWindowAttributes(IntPtr hWnd, uint crKey,
                                                             byte bAlpha, LWA dwFlags);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetLayeredWindowAttributes(IntPtr hWnd, out uint crKey, out byte bAlpha,
                                                             out uint dwFlags);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetLayeredWindowAttributes(IntPtr hWnd, out uint crKey, out byte bAlpha,
                                                             out LWA dwFlags);

        /// <summary>
        /// Функция SetWindowLong изменяет атрибуты определяемого окна. 
        /// Функция также устанавливает 32-разрядное (длинное) значение 
        /// при заданном смещении в дополнительном пространстве памяти об окне
        /// </summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="nIndex">
        /// Определяет значение смещения, отсчитываемое от нуля, которое будет установлено. 
        /// Допустимые значения находятся в диапазоне от нуля до числа байтов дополнительного 
        /// пространства в памяти, минус 4; например, если бы Вы установили 12 или большее 
        /// количество байтов памяти дополнительного пространства, значение 8 было бы индексом 
        /// к третьему 32-разрядному целому числу.
        /// </param>
        /// <param name="dwNewLong">Устанавливает восстановленное значение</param>
        /// <returns>
        /// Если функция завершается успешно, возвращаемое значение - предыдущее значение 
        /// заданного 32-разрядного целого числа. Если функция не выполняет задачу, 
        /// возвращаемое значение нулевое
        /// </returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        [DllImport(FileName, SetLastError = true)]
        public static extern int GetWindowLong(IntPtr hWnd, int nIndex);

        /// <summary>
        /// Функция SetWindowLong изменяет атрибуты определяемого окна. 
        /// Функция также устанавливает 32-разрядное (длинное) значение 
        /// при заданном смещении в дополнительном пространстве памяти об окне
        /// </summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="nIndex">
        /// Определяет значение смещения, отсчитываемое от нуля, которое будет установлено. 
        /// Допустимые значения находятся в диапазоне от нуля до числа байтов дополнительного 
        /// пространства в памяти, минус 4; например, если бы Вы установили 12 или большее 
        /// количество байтов памяти дополнительного пространства, значение 8 было бы индексом 
        /// к третьему 32-разрядному целому числу.
        /// </param>
        /// <param name="dwNewLong">Устанавливает восстановленное значение</param>
        /// <returns>
        /// Если функция завершается успешно, возвращаемое значение - предыдущее значение 
        /// заданного 32-разрядного целого числа. Если функция не выполняет задачу, 
        /// возвращаемое значение нулевое
        /// </returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern int SetWindowLong(IntPtr hWnd, GWL nIndex, WS dwNewLong);

        [DllImport(FileName, SetLastError = true)]
        public static extern WS GetWindowLong(IntPtr hWnd, GWL nIndex);


        // This static method is required because legacy OSes do not support
        // SetWindowLongPtr 
        public static IntPtr SetWindowLongPtr(HandleRef hWnd, int nIndex, IntPtr dwNewLong)
        {
            return IntPtr.Size == 8
                               ? SetWindowLongPtr64(hWnd, nIndex, dwNewLong)
                               : new IntPtr(SetWindowLong32(hWnd, nIndex, dwNewLong.ToInt32()));
        }

        [DllImport(FileName, EntryPoint = "SetWindowLong", SetLastError = true)]
        private static extern int SetWindowLong32(HandleRef hWnd, int nIndex, int dwNewLong);

        [DllImport(FileName, EntryPoint = "SetWindowLongPtr", SetLastError = true)]
        private static extern IntPtr SetWindowLongPtr64(HandleRef hWnd, int nIndex, IntPtr dwNewLong);

        [DllImport(FileName, SetLastError = true)]
        public static extern void DisableProcessWindowsGhosting();

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetNextWindow(IntPtr hWnd, GW wCmd);

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetTopWindow(IntPtr hWnd);

        [DllImport(FileName, ExactSpelling = true, CharSet = CharSet.Auto)]
        public static extern IntPtr GetParent(IntPtr hWnd);

        #region CreateWindow

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr CreateWindow(
            string lpClassName,    //  указатель на зарегистрированное имя класса
            string lpWindowName,   //  указатель на имя окна
            WindowStyles dwStyle,          //  стиль окна
            int x, int y,
            int nWidth, int nHeight,
            IntPtr hWndParent,        //  дескриптор родительского или окна владельца
            IntPtr hMenu,            //  дескриптор меню или ID  дочернего окна
            IntPtr hInstance,       //  дескриптор экземпляра приложения
            IntPtr lpParam         //  указатель на данные создания окна
           );

        /// <summary>
        /// The CreateWindowEx function creates an overlapped, pop-up, or child window with an extended window style; otherwise, this function is identical to the CreateWindow function. 
        /// </summary>
        /// <param name="dwExStyle">Specifies the extended window style of the window being created.</param>
        /// <param name="lpClassName">Pointer to a null-terminated string or a class atom created by a previous call to the RegisterClass or RegisterClassEx function. The atom must be in the low-order word of lpClassName; the high-order word must be zero. If lpClassName is a string, it specifies the window class name. The class name can be any name registered with RegisterClass or RegisterClassEx, provided that the module that registers the class is also the module that creates the window. The class name can also be any of the predefined system class names.</param>
        /// <param name="lpWindowName">Pointer to a null-terminated string that specifies the window name. If the window style specifies a title bar, the window title pointed to by lpWindowName is displayed in the title bar. When using CreateWindow to create controls, such as buttons, check boxes, and static controls, use lpWindowName to specify the text of the control. When creating a static control with the SS_ICON style, use lpWindowName to specify the icon name or identifier. To specify an identifier, use the syntax "#num". </param>
        /// <param name="dwStyle">Specifies the style of the window being created. This parameter can be a combination of window styles, plus the control styles indicated in the Remarks section.</param>
        /// <param name="x">Specifies the initial horizontal position of the window. For an overlapped or pop-up window, the x parameter is the initial x-coordinate of the window's upper-left corner, in screen coordinates. For a child window, x is the x-coordinate of the upper-left corner of the window relative to the upper-left corner of the parent window's client area. If x is set to CW_USEDEFAULT, the system selects the default position for the window's upper-left corner and ignores the y parameter. CW_USEDEFAULT is valid only for overlapped windows; if it is specified for a pop-up or child window, the x and y parameters are set to zero.</param>
        /// <param name="y">Specifies the initial vertical position of the window. For an overlapped or pop-up window, the y parameter is the initial y-coordinate of the window's upper-left corner, in screen coordinates. For a child window, y is the initial y-coordinate of the upper-left corner of the child window relative to the upper-left corner of the parent window's client area. For a list box y is the initial y-coordinate of the upper-left corner of the list box's client area relative to the upper-left corner of the parent window's client area.
        /// <para>If an overlapped window is created with the WS_VISIBLE style bit set and the x parameter is set to CW_USEDEFAULT, then the y parameter determines how the window is shown. If the y parameter is CW_USEDEFAULT, then the window manager calls ShowWindow with the SW_SHOW flag after the window has been created. If the y parameter is some other value, then the window manager calls ShowWindow with that value as the nCmdShow parameter.</para></param>
        /// <param name="nWidth">Specifies the width, in device units, of the window. For overlapped windows, nWidth is the window's width, in screen coordinates, or CW_USEDEFAULT. If nWidth is CW_USEDEFAULT, the system selects a default width and height for the window; the default width extends from the initial x-coordinates to the right edge of the screen; the default height extends from the initial y-coordinate to the top of the icon area. CW_USEDEFAULT is valid only for overlapped windows; if CW_USEDEFAULT is specified for a pop-up or child window, the nWidth and nHeight parameter are set to zero.</param>
        /// <param name="nHeight">Specifies the height, in device units, of the window. For overlapped windows, nHeight is the window's height, in screen coordinates. If the nWidth parameter is set to CW_USEDEFAULT, the system ignores nHeight.</param> <param name="hWndParent">Handle to the parent or owner window of the window being created. To create a child window or an owned window, supply a valid window handle. This parameter is optional for pop-up windows.
        /// <para>Windows 2000/XP: To create a message-only window, supply HWND_MESSAGE or a handle to an existing message-only window.</para></param>
        /// <param name="hMenu">Handle to a menu, or specifies a child-window identifier, depending on the window style. For an overlapped or pop-up window, hMenu identifies the menu to be used with the window; it can be NULL if the class menu is to be used. For a child window, hMenu specifies the child-window identifier, an integer value used by a dialog box control to notify its parent about events. The application determines the child-window identifier; it must be unique for all child windows with the same parent window.</param>
        /// <param name="hInstance">Handle to the instance of the module to be associated with the window.</param> <param name="lpParam">Pointer to a value to be passed to the window through the CREATESTRUCT structure (lpCreateParams member) pointed to by the lParam param of the WM_CREATE message. This message is sent to the created window by this function before it returns.
        /// <para>If an application calls CreateWindow to create a MDI client window, lpParam should point to a CLIENTCREATESTRUCT structure. If an MDI client window calls CreateWindow to create an MDI child window, lpParam should point to a MDICREATESTRUCT structure. lpParam may be NULL if no additional data is needed.</para></param>
        /// <returns>If the function succeeds, the return value is a handle to the new window.
        /// <para>If the function fails, the return value is NULL. To get extended error information, call GetLastError.</para>
        /// <para>This function typically fails for one of the following reasons:</para>
        /// <list type="">
        /// <item>an invalid parameter value</item>
        /// <item>the system class was registered by a different module</item>
        /// <item>The WH_CBT hook is installed and returns a failure code</item>
        /// <item>if one of the controls in the dialog template is not registered, or its window window procedure fails WM_CREATE or WM_NCCREATE</item>
        /// </list></returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr CreateWindowEx(
           WindowStylesEx dwExStyle,
           string lpClassName,
           string lpWindowName,
           WindowStyles dwStyle,
           int x, int y,
           int nWidth, int nHeight,
           IntPtr hWndParent,
           IntPtr hMenu,
           IntPtr hInstance,
           IntPtr lpParam);

        #endregion

        [DllImport(FileName, SetLastError = true)]
        public static extern bool EnumDesktopWindows(IntPtr hDesktop, EnumWindowProc lpfn, IntPtr lParam);

        /// <summary>Функция извлекает данные о состоянии видимости заданного окна.</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Истина, если окно видимо</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool IsWindowVisible(IntPtr hWnd);

        /// <summary>Функция определяет, идентифицирует ли дескриптор определяемого окна существующее окно</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Если дескриптор окна идентифицирует существующее окно, возвращаемое значение истина</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool IsWindow(IntPtr hWnd);

        public static IntPtr GetClassLong_Safe(IntPtr hWnd, ClassLongFlags nIndex)
        {
#pragma warning disable 612,618
            return IntPtr.Size > 4 ? GetClassLongPtr(hWnd, nIndex) : GetClassLong(hWnd, nIndex);
#pragma warning restore 612,618
        }

        [Obsolete("This method will crash on 64-bit operating systems. Use GetClassLongPtr instead")]
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetClassLong(IntPtr hWnd, ClassLongFlags nIndex);

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetClassLongPtr(IntPtr hWnd, ClassLongFlags nIndex);

        public static IntPtr SetClassLong_Safe(IntPtr hWnd, ClassLongFlags nIndex, IntPtr dwNewLong)
        {
#pragma warning disable 612,618
            return IntPtr.Size > 4 ? SetClassLongPtr(hWnd, nIndex, dwNewLong) : SetClassLong(hWnd, nIndex, unchecked((uint)dwNewLong.ToInt32()));
#pragma warning restore 612,618
        }

        [Obsolete("This method will crash on 64-bit operating systems. Use SetClassLongPtr instead")]
        [DllImport(FileName, SetLastError = true)]
        static extern IntPtr SetClassLong(IntPtr hWnd, ClassLongFlags nIndex, uint dwNewLong);

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr SetClassLongPtr(IntPtr hWnd, ClassLongFlags nIndex, IntPtr dwNewLong);

        /// <summary>
        /// Функция замещает 16-битное (слово) значение по указанному смещении в дополнительной памяти оконного класса, 
        /// к которому относится указанное окно
        /// </summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="nIndex">Определяет замещаемое значение</param>
        /// <param name="wNewWord">Новое значение</param>
        /// <returns>
        /// При успешном завершении, функция возвращает предыдущее 16-битное значение.
        /// При ошибке возвращается ноль. Для получения дополнительной информации об ошибке, вызовите GetLastError
        /// </returns>
        [DllImport(FileName, SetLastError = true)]
        [Obsolete("GWW_значения являются устаревшими в Win32. Вы должны использовать функцию SetClassLong для установки значений класса, которые были до этого установлены функцией SetClassWord при использовании GCW_значений")]
        public static extern ushort SetClassWord(IntPtr hWnd, ClassLongFlags nIndex, ushort wNewWord);

        /// <summary>
        /// Функция GetClassWord получает 16-битное (слово) значение в указанном смещении из дополнительной памяти 
        /// для оконного класса, к которому относится указанное окно.
        /// 
        /// GCW_значения в Win32 API являются устаревшими, кроме GCW_ATOM и GCW_HICONSM. 
        /// Вы должны использовать функцию GetClassLong для получения значений класса окна
        /// </summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="nIndex">Определяет замещаемое значение</param>
        /// <returns>
        /// При успешном завершении, функция возвращает затребованное 16-битное значение.
        /// При ошибке возвращается ноль. Для получения дополнительной информации об ошибке, вызовите GetLastError
        /// </returns>
        [DllImport(FileName, SetLastError = true)]
        [Obsolete("GWW_значения являются устаревшими в Win32. Вы должны использовать функцию SetClassLong для установки значений класса, которые были до этого установлены функцией SetClassWord при использовании GCW_значений")]
        public static extern ushort GetClassWord(IntPtr hWnd, ClassLongFlags nIndex);

        /// <summary>Проверка окна на зависание</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Истина, если окно приложения не отвечает</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool IsHungAppWindow(IntPtr hWnd);

        /// <summary>
        /// Функция  извлекает дескриптор окна (если он есть), который захватил мышь. 
        /// Одновременно только одно окно может захватить мышь; это окно получает ввод данных от мыши, 
        /// в любом случае, есть или нет курсора внутри его границ
        /// </summary>
        /// <returns>
        /// Возвращаемое значение - дескриптор окна захвата, связанное с текущим потоком. 
        /// Если в потоке нет окна, захватившего мышь, возвращаемое значение - ПУСТО
        /// 
        /// Возвращаемое значение ПУСТО (NULL) означает, что текущий поток не захватил мышь. 
        /// Однако, возможно, что другой поток или процесс захватил мышь
        /// </returns>
        /// <remarks>Чтобы получить дескриптор окна захвата в другом потоке, используйте функцию <see cref="GetGUIThreadInfo"/></remarks>
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr GetCapture();

        /// <summary>
        /// Функция извлекает информацию об активном окне или заданном потоке графического интерфейса пользователя (GUI)
        /// </summary>
        /// <param name="idThread">
        /// Идентифицирует поток, информация о котором должна быть получена. 
        /// Чтобы извлечь это значение, используйте функцию <see cref="GetWindowThreadProcessId"/>. 
        /// Если этот параметр имеет значение ПУСТО (NULL), функции возвращает информацию о приоритетном потоке
        /// </param>
        /// <param name="lpgui">Указатель на структуру <see cref="GUIThreadInfo"/>, которая получает информацию, описывающую поток</param>
        /// <returns>
        /// Если функция завершается успешно, величина возвращаемого значения - не ноль.
        /// Если функция завершается с ошибкой, величина возвращаемого значения - ноль. 
        /// Чтобы получать расширенные данные об ошибках, вызовите функцию GetLastError
        /// </returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool GetGUIThreadInfo(uint idThread, out GUIThreadInfo lpgui);

        /// <summary>Функция IsChild проверяет, является ли окно дочерним окном или порожденным окном определяемого родительского окна. </summary>
        /// <remarks>
        /// Дочернее окно - прямой потомок определяемого родительского окна, 
        /// если это родительское окно находится в цепочке родительских окон; 
        /// цепочка родительских окон управляет в диапазоне от оригинала перекрывающего или выскакивающего окна до дочернего окна
        /// </remarks>
        /// <param name="hWndParent">Дескриптор родительского окна</param>
        /// <param name="hWnd">Дескриптор проверяемого окна</param>
        /// <returns>Истина, если проверяемое окно является дочерним, либо если окно в цепочке наследников окна</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool IsChild(IntPtr hWndParent, IntPtr hWnd);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool IsIconic(IntPtr hWnd);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool IsZoomed(IntPtr hWnd);

        /// <summary>
        /// Функция восстанавливает свернутое (иконизированное) окно в его предыдущих размерах и позиции; затем она активизирует его
        /// </summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <returns>Если операция выполнена - истина</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool OpenIcon(IntPtr hWnd);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool FlashWindow(IntPtr hWnd, bool bInvert);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool FlashWindowEx(ref FlashWInfo pwfi);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool PrintWindow(IntPtr hWnd, IntPtr hDC, uint nFlags);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool PrintWindow(IntPtr hWnd, IntPtr hDC, PW nFlags = PW.Default);

        /// <summary>Дает возможность создания особых эффектов при появлении или скрытии окна</summary>
        /// <param name="hWnd">Дескриптор окна</param>
        /// <param name="Time">Время, отведенное для анимации(в миллисекундах)</param>
        /// <param name="Flags">Флаг, определяющий тип анимации</param>
        /// <returns>Истина, если функция выполнена успешно</returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool AnimateWindow(IntPtr hWnd, int Time, AnimateWindowFlags Flags);

        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetTitleBarInfo(IntPtr hwnd, ref TitleBarInfo Info);

        /// <summary>Retrieves the show state and the restored, minimized, and maximized positions of the specified window.</summary>
        /// <param name="hWnd">A handle to the window.</param>
        /// <param name="lpwndpl">
        /// A pointer to the WindowPlacement structure that receives the show state and position information.
        /// <para>
        /// Before calling GetWindowPlacement, set the length member to sizeof(WindowPlacement). GetWindowPlacement fails if lpwndpl-> length is not set correctly.
        /// </para>
        /// </param>
        /// <returns>
        /// If the function succeeds, the return value is nonzero.
        /// <para>
        /// If the function fails, the return value is zero. To get extended error information, call GetLastError.
        /// </para>
        /// </returns>
        [DllImport(FileName, SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        public static extern bool GetWindowPlacement(IntPtr hWnd, [Out] out WindowPlacement lpwndpl);

        /// <summary>
        /// Sets the show state and the restored, minimized, and maximized positions of the specified window.
        /// </summary>
        /// <param name="hWnd">A handle to the window.</param>
        /// <param name="lpwndpl">
        /// A pointer to a WINDOWPLACEMENT structure that specifies the new show state and window positions.
        /// <para>
        /// Before calling SetWindowPlacement, set the length member of the WINDOWPLACEMENT structure to sizeof(WINDOWPLACEMENT). SetWindowPlacement fails if the length member is not set correctly.
        /// </para>
        /// </param>
        /// <returns><para>Истина, если функция выполнена успешно</para></returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool SetWindowPlacement(IntPtr hWnd, [In] WindowPlacement lpwndpl);

        /// <summary>Рисует один из элементов в заголовке окна</summary>
        /// <param name="hDC">Дескриптор графического контекста устройства, на котором происходит рисование</param>
        /// <param name="lprc">Область в которой будет происходить рисование</param>
        /// <param name="uType">Тип элемента</param>
        /// <param name="uState">Стиль элемента</param>
        /// <returns></returns>
        [DllImport(FileName, SetLastError = true)]
        public static extern bool DrawFrameControl(IntPtr hDC, RECT lprc, DFC uType, DFCS uState);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool EnumThreadWindows(uint dwThreadId, EnumThreadDelegate lpfn, IntPtr lParam);

        // IntPtr mem = IntPtr.Zero;
        // try {
        //      mem = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(DevBroadcastDeviceInterfaceBuffer)));
        //      Marshal.StructureToPtr(new DevBroadcastDeviceInterfaceBuffer(5), mem, false);
        //      RegisterDeviceNotification(YOUR_HANDLE_HERE_D00D, mem, 0);
        //      // Sure hope you overrode your WndProc function
        // }
        // catch (Exception e) {
        //      //Log this
        // }
        // finally {
        //      Marshal.FreeHGlobal(mem);
        // }
        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr RegisterDeviceNotification(
            IntPtr hRecipient,
            DevBroadcastDeviceInterfaceBuffer NotificationFilter,
            uint Flags);

        [DllImport(FileName, SetLastError = true)]
        public static extern IntPtr RegisterDeviceNotification(
            IntPtr hRecipient,
            DeviceBroadcastInterface NotificationFilter,
            uint Flags);

        [DllImport(FileName, SetLastError = true)]
        public static extern bool UnregisterDeviceNotification(IntPtr Handle);

        [DllImport(FileName, ExactSpelling = true)]
        public static extern int GetMessagePos();

        [DllImport(FileName, ExactSpelling = true)]
        public static extern int GetMessageTime();

        /// <summary>
        /// Функция ClipCursor ограничивает перемещение курсора в прямоугольной области экрана. 
        /// Если последующая позиция курсора (установленная функцией SetCursorPos или мышью) 
        /// лежит вне пределов этого прямоугольника, система автоматически корректирует позицию, 
        /// чтобы сохранить курсор внутри прямоугольной области
        /// </summary>
        /// <param name="lpRect">
        /// Указывает на структуру RECT, которая содержит экранные координаты левого верхнего и нижнего правого углов 
        /// ограничивающего прямоугольника. Если этот параметр равен значению ПУСТО (NULL), курсор освобождается для 
        /// передвижения в любое место экрана</param>
        /// <returns>Если функция завершилась успешно, возвращаемое значение - истина</returns>
        [DllImport(FileName)]
        public static extern bool ClipCursor([In] RECT lpRect);

        /// <summary>Функция извлекает информацию об экранных координатах прямоугольной области, которой ограничен курсор</summary>
        /// <param name="lpRect">
        /// Указывает на структуру RECT, которая принимает экранные координаты ограничивающего прямоугольника. 
        /// Структура принимает размеры экрана, если курсор не ограничен прямоугольником
        /// </param>
        /// <returns>Если функция завершается успешно, возвращаемое значение - истина</returns>
        [DllImport(FileName)]
        public static extern bool GetClipCursor([Out] out RECT lpRect);
    }

    public enum LSFW { Lock = 1, Unlock = 2 }

    [Serializable]
    public enum HKL { Prev = 0, Next = 1 }

    [Flags, Serializable]
    public enum KLF
    {
        Activate = 0x00000001,
        Substitute_OK = 0x00000002,
        Reorder = 0x00000008,
        ReplaceLang = 0x00000010,
        NoTellShell = 0x00000080,
        SetForProcess = 0x00000100,
        ShiftLock = 0x00010000,
        Reset = 0x40000000,

        //[Obsolete("NotSuported. Use UnloadKeyboardLayout", true)]
        //UnloadPrevious
    }

    /// <summary>
    /// ANIMATIONINFO specifies animation effects associated with user actions. 
    /// Used with SystemParametersInfo when SPI_GETANIMATION or SPI_SETANIMATION action is specified.
    /// </summary>
    /// <remark>The uiParam value must be set to (int)Marshal.SizeOf(typeof(ANIMATIONINFO)) when using this structure.</remark>
    [StructLayout(LayoutKind.Sequential)]
    public struct ANIMATIONINFO
    {
        /// <summary>Always must be set to (int)Marshal.SizeOf(typeof(ANIMATIONINFO)).</summary>
        public uint cbSize;

        /// <summary>If non-zero, minimize/restore animation is enabled, otherwise disabled.</summary>
        public int iMinAnimate;

        /// <summary>Creates an AMINMATIONINFO structure.</summary>
        /// <param name="iMinAnimate">If non-zero and SPI_SETANIMATION is specified, enables minimize/restore animation.</param>
        public ANIMATIONINFO(int iMinAnimate)
        {
            cbSize = (uint)Marshal.SizeOf(typeof(ANIMATIONINFO));
            this.iMinAnimate = iMinAnimate;
        }
    }

    #region SPI
    /// <summary>SPI_ System-wide parameter - Used in SystemParametersInfo function </summary>
    [Description("SPI_(System-wide parameter - Used in SystemParametersInfo function )")]
    public enum SPI : uint
    {
        /// <summary>
        /// Determines whether the warning beeper is on. 
        /// The pvParam parameter must point to a BOOL variable that receives TRUE if the beeper is on, or FALSE if it is off.
        /// </summary>
        GETBEEP = 0x0001,

        /// <summary>Turns the warning beeper on or off. The uiParam parameter specifies TRUE for on, or FALSE for off.</summary>
        SETBEEP = 0x0002,

        /// <summary>Retrieves the two mouse threshold values and the mouse speed.</summary>
        GETMOUSE = 0x0003,

        /// <summary>Sets the two mouse threshold values and the mouse speed.</summary>
        SETMOUSE = 0x0004,

        /// <summary>
        /// Retrieves the border multiplier factor that determines the width of a window's sizing border. 
        /// The pvParam parameter must point to an integer variable that receives this value.
        /// </summary>
        GETBORDER = 0x0005,

        /// <summary>
        /// Sets the border multiplier factor that determines the width of a window's sizing border. 
        /// The uiParam parameter specifies the new value.
        /// </summary>
        SETBORDER = 0x0006,

        /// <summary>
        /// Retrieves the keyboard repeat-speed setting, which is a value in the range from 0 (approximately 2.5 repetitions per second) 
        /// through 31 (approximately 30 repetitions per second). The actual repeat rates are hardware-dependent and may vary from 
        /// a linear scale by as much as 20%. The pvParam parameter must point to a DWORD variable that receives the setting
        /// </summary>
        GETKEYBOARDSPEED = 0x000A,

        /// <summary>
        /// Sets the keyboard repeat-speed setting. The uiParam parameter must specify a value in the range from 0 
        /// (approximately 2.5 repetitions per second) through 31 (approximately 30 repetitions per second). 
        /// The actual repeat rates are hardware-dependent and may vary from a linear scale by as much as 20%. 
        /// If uiParam is greater than 31, the parameter is set to 31.
        /// </summary>
        SETKEYBOARDSPEED = 0x000B,

        /// <summary>Not implemented.</summary>
        LANGDRIVER = 0x000C,

        /// <summary>
        /// Sets or retrieves the width, in pixels, of an icon cell. The system uses this rectangle to arrange icons in large icon view. 
        /// To set this value, set uiParam to the new value and set pvParam to null. You cannot set this value to less than SM_CXICON.
        /// To retrieve this value, pvParam must point to an integer that receives the current value.
        /// </summary>
        ICONHORIZONTALSPACING = 0x000D,

        /// <summary>
        /// Retrieves the screen saver time-out value, in seconds. The pvParam parameter must point to an integer variable that receives the value.
        /// </summary>
        GETSCREENSAVETIMEOUT = 0x000E,

        /// <summary>
        /// Sets the screen saver time-out value to the value of the uiParam parameter. This value is the amount of time, in seconds, 
        /// that the system must be idle before the screen saver activates.
        /// </summary>
        SETSCREENSAVETIMEOUT = 0x000F,

        /// <summary>
        /// Determines whether screen saving is enabled. The pvParam parameter must point to a bool variable that receives TRUE 
        /// if screen saving is enabled, or FALSE otherwise.
        /// </summary>
        GETSCREENSAVEACTIVE = 0x0010,

        /// <summary>
        /// Sets the state of the screen saver. The uiParam parameter specifies TRUE to activate screen saving, or FALSE to deactivate it.
        /// </summary>
        SETSCREENSAVEACTIVE = 0x0011,

        /// <summary>
        /// Retrieves the current granularity value of the desktop sizing grid. The pvParam parameter must point to an integer variable 
        /// that receives the granularity.
        /// </summary>
        GETGRIDGRANULARITY = 0x0012,

        /// <summary>
        /// Sets the granularity of the desktop sizing grid to the value of the uiParam parameter.
        /// </summary>
        SETGRIDGRANULARITY = 0x0013,

        /// <summary>
        /// Sets the desktop wallpaper. The value of the pvParam parameter determines the new wallpaper. To specify a wallpaper bitmap, 
        /// set pvParam to point to a null-terminated string containing the name of a bitmap file. Setting pvParam to "" removes the wallpaper. 
        /// Setting pvParam to SETWALLPAPER_DEFAULT or null reverts to the default wallpaper.
        /// </summary>
        SETDESKWALLPAPER = 0x0014,

        /// <summary>
        /// Sets the current desktop pattern by causing Windows to read the Pattern= setting from the WIN.INI file.
        /// </summary>
        SETDESKPATTERN = 0x0015,

        /// <summary>
        /// Retrieves the keyboard repeat-delay setting, which is a value in the range from 0 (approximately 250 ms delay) through 3 
        /// (approximately 1 second delay). The actual delay associated with each value may vary depending on the hardware. The pvParam parameter must point to an integer variable that receives the setting.
        /// </summary>
        GETKEYBOARDDELAY = 0x0016,

        /// <summary>
        /// Sets the keyboard repeat-delay setting. The uiParam parameter must specify 0, 1, 2, or 3, where zero sets the shortest delay 
        /// (approximately 250 ms) and 3 sets the longest delay (approximately 1 second). The actual delay associated with each value may 
        /// vary depending on the hardware.
        /// </summary>
        SETKEYBOARDDELAY = 0x0017,

        /// <summary>
        /// Sets or retrieves the height, in pixels, of an icon cell. 
        /// To set this value, set uiParam to the new value and set pvParam to null. You cannot set this value to less than SM_CYICON.
        /// To retrieve this value, pvParam must point to an integer that receives the current value.
        /// </summary>
        ICONVERTICALSPACING = 0x0018,

        /// <summary>
        /// Determines whether icon-title wrapping is enabled. The pvParam parameter must point to a bool variable that receives TRUE 
        /// if enabled, or FALSE otherwise.
        /// </summary>
        GETICONTITLEWRAP = 0x0019,

        /// <summary>
        /// Turns icon-title wrapping on or off. The uiParam parameter specifies TRUE for on, or FALSE for off.
        /// </summary>
        SETICONTITLEWRAP = 0x001A,

        /// <summary>
        /// Determines whether pop-up menus are left-aligned or right-aligned, relative to the corresponding menu-bar item.
        /// The pvParam parameter must point to a bool variable that receives TRUE if left-aligned, or FALSE otherwise.
        /// </summary>
        GETMENUDROPALIGNMENT = 0x001B,

        /// <summary>
        /// Sets the alignment value of pop-up menus. The uiParam parameter specifies TRUE for right alignment, or FALSE for left alignment.
        /// </summary>
        SETMENUDROPALIGNMENT = 0x001C,

        /// <summary>
        /// Sets the width of the double-click rectangle to the value of the uiParam parameter. 
        /// The double-click rectangle is the rectangle within which the second click of a double-click must fall for it to be registered 
        /// as a double-click.
        /// To retrieve the width of the double-click rectangle, call GetSystemMetrics with the SM_CXDOUBLECLK flag.
        /// </summary>
        SETDOUBLECLKWIDTH = 0x001D,

        /// <summary>
        /// Sets the height of the double-click rectangle to the value of the uiParam parameter. 
        /// The double-click rectangle is the rectangle within which the second click of a double-click must fall for it to be registered 
        /// as a double-click.
        /// To retrieve the height of the double-click rectangle, call GetSystemMetrics with the SM_CYDOUBLECLK flag.
        /// </summary>
        SETDOUBLECLKHEIGHT = 0x001E,

        /// <summary>
        /// Retrieves the logical font information for the current icon-title font. The uiParam parameter specifies the size of a LOGFONT structure, 
        /// and the pvParam parameter must point to the LOGFONT structure to fill in.
        /// </summary>
        GETICONTITLELOGFONT = 0x001F,

        /// <summary>
        /// Sets the double-click time for the mouse to the value of the uiParam parameter. The double-click time is the maximum number 
        /// of milliseconds that can occur between the first and second clicks of a double-click. You can also call the SetDoubleClickTime 
        /// function to set the double-click time. To get the current double-click time, call the GetDoubleClickTime function.
        /// </summary>
        SETDOUBLECLICKTIME = 0x0020,

        /// <summary>
        /// Swaps or restores the meaning of the left and right mouse buttons. The uiParam parameter specifies TRUE to swap the meanings 
        /// of the buttons, or FALSE to restore their original meanings.
        /// </summary>
        SETMOUSEBUTTONSWAP = 0x0021,

        /// <summary>
        /// Sets the font that is used for icon titles. The uiParam parameter specifies the size of a LOGFONT structure, 
        /// and the pvParam parameter must point to a LOGFONT structure.
        /// </summary>
        SETICONTITLELOGFONT = 0x0022,

        /// <summary>
        /// This flag is obsolete. Previous versions of the system use this flag to determine whether ALT+TAB fast task switching is enabled. 
        /// For Windows 95, Windows 98, and Windows NT version 4.0 and later, fast task switching is always enabled.
        /// </summary>
        GETFASTTASKSWITCH = 0x0023,

        /// <summary>
        /// This flag is obsolete. Previous versions of the system use this flag to enable or disable ALT+TAB fast task switching. 
        /// For Windows 95, Windows 98, and Windows NT version 4.0 and later, fast task switching is always enabled.
        /// </summary>
        SETFASTTASKSWITCH = 0x0024,

        //#if(WINVER >= 0x0400)
        /// <summary>
        /// Sets dragging of full windows either on or off. The uiParam parameter specifies TRUE for on, or FALSE for off. 
        /// Windows 95:  This flag is supported only if Windows Plus! is installed. See SPI_GETWINDOWSEXTENSION.
        /// </summary>
        SETDRAGFULLWINDOWS = 0x0025,

        /// <summary>
        /// Determines whether dragging of full windows is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if enabled, or FALSE otherwise. 
        /// Windows 95:  This flag is supported only if Windows Plus! is installed. See SPI_GETWINDOWSEXTENSION.
        /// </summary>
        GETDRAGFULLWINDOWS = 0x0026,

        /// <summary>
        /// Retrieves the metrics associated with the nonclient area of nonminimized windows. The pvParam parameter must point 
        /// to a NONCLIENTMETRICS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter 
        /// to sizeof(NONCLIENTMETRICS).
        /// </summary>
        GETNONCLIENTMETRICS = 0x0029,

        /// <summary>
        /// Sets the metrics associated with the nonclient area of nonminimized windows. The pvParam parameter must point 
        /// to a NONCLIENTMETRICS structure that contains the new parameters. Set the cbSize member of this structure 
        /// and the uiParam parameter to sizeof(NONCLIENTMETRICS). Also, the lfHeight member of the LOGFONT structure must be a negative value.
        /// </summary>
        SETNONCLIENTMETRICS = 0x002A,

        /// <summary>
        /// Retrieves the metrics associated with minimized windows. The pvParam parameter must point to a MINIMIZEDMETRICS structure 
        /// that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(MINIMIZEDMETRICS).
        /// </summary>
        GETMINIMIZEDMETRICS = 0x002B,

        /// <summary>
        /// Sets the metrics associated with minimized windows. The pvParam parameter must point to a MINIMIZEDMETRICS structure 
        /// that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(MINIMIZEDMETRICS).
        /// </summary>
        SETMINIMIZEDMETRICS = 0x002C,

        /// <summary>
        /// Retrieves the metrics associated with icons. The pvParam parameter must point to an ICONMETRICS structure that receives 
        /// the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(ICONMETRICS).
        /// </summary>
        GETICONMETRICS = 0x002D,

        /// <summary>
        /// Sets the metrics associated with icons. The pvParam parameter must point to an ICONMETRICS structure that contains 
        /// the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(ICONMETRICS).
        /// </summary>
        SETICONMETRICS = 0x002E,

        /// <summary>
        /// Sets the size of the work area. The work area is the portion of the screen not obscured by the system taskbar 
        /// or by application desktop toolbars. The pvParam parameter is a pointer to a RECT structure that specifies the new work area rectangle, 
        /// expressed in virtual screen coordinates. In a system with multiple display monitors, the function sets the work area 
        /// of the monitor that contains the specified rectangle.
        /// </summary>
        SETWORKAREA = 0x002F,

        /// <summary>
        /// Retrieves the size of the work area on the primary display monitor. The work area is the portion of the screen not obscured 
        /// by the system taskbar or by application desktop toolbars. The pvParam parameter must point to a RECT structure that receives 
        /// the coordinates of the work area, expressed in virtual screen coordinates. 
        /// To get the work area of a monitor other than the primary display monitor, call the GetMonitorInfo function.
        /// </summary>
        GETWORKAREA = 0x0030,

        /// <summary>
        /// Windows Me/98/95:  Pen windows is being loaded or unloaded. The uiParam parameter is TRUE when loading and FALSE 
        /// when unloading pen windows. The pvParam parameter is null.
        /// </summary>
        SETPENWINDOWS = 0x0031,

        /// <summary>
        /// Retrieves information about the HighContrast accessibility feature. The pvParam parameter must point to a HIGHCONTRAST structure 
        /// that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(HIGHCONTRAST). 
        /// For a general discussion, see remarks.
        /// Windows NT:  This value is not supported.
        /// </summary>
        /// <remarks>
        /// There is a difference between the High Contrast color scheme and the High Contrast Mode. The High Contrast color scheme changes 
        /// the system colors to colors that have obvious contrast; you switch to this color scheme by using the Display Options in the control panel. 
        /// The High Contrast Mode, which uses SPI_GETHIGHCONTRAST and SPI_SETHIGHCONTRAST, advises applications to modify their appearance 
        /// for visually-impaired users. It involves such things as audible warning to users and customized color scheme 
        /// (using the Accessibility Options in the control panel). For more information, see HIGHCONTRAST on MSDN.
        /// For more information on general accessibility features, see Accessibility on MSDN.
        /// </remarks>
        GETHIGHCONTRAST = 0x0042,

        /// <summary>
        /// Sets the parameters of the HighContrast accessibility feature. The pvParam parameter must point to a HIGHCONTRAST structure 
        /// that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(HIGHCONTRAST).
        /// Windows NT:  This value is not supported.
        /// </summary>
        SETHIGHCONTRAST = 0x0043,

        /// <summary>
        /// Determines whether the user relies on the keyboard instead of the mouse, and wants applications to display keyboard interfaces 
        /// that would otherwise be hidden. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if the user relies on the keyboard; or FALSE otherwise.
        /// Windows NT:  This value is not supported.
        /// </summary>
        GETKEYBOARDPREF = 0x0044,

        /// <summary>
        /// Sets the keyboard preference. The uiParam parameter specifies TRUE if the user relies on the keyboard instead of the mouse, 
        /// and wants applications to display keyboard interfaces that would otherwise be hidden; uiParam is FALSE otherwise.
        /// Windows NT:  This value is not supported.
        /// </summary>
        SETKEYBOARDPREF = 0x0045,

        /// <summary>
        /// Determines whether a screen reviewer utility is running. A screen reviewer utility directs textual information to an output device, 
        /// such as a speech synthesizer or Braille display. When this flag is set, an application should provide textual information 
        /// in situations where it would otherwise present the information graphically.
        /// The pvParam parameter is a pointer to a BOOL variable that receives TRUE if a screen reviewer utility is running, or FALSE otherwise.
        /// Windows NT:  This value is not supported.
        /// </summary>
        GETSCREENREADER = 0x0046,

        /// <summary>
        /// Determines whether a screen review utility is running. The uiParam parameter specifies TRUE for on, or FALSE for off.
        /// Windows NT:  This value is not supported.
        /// </summary>
        SETSCREENREADER = 0x0047,

        /// <summary>
        /// Retrieves the animation effects associated with user actions. The pvParam parameter must point to an ANIMATIONINFO structure 
        /// that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(ANIMATIONINFO).
        /// </summary>
        GETANIMATION = 0x0048,

        /// <summary>
        /// Sets the animation effects associated with user actions. The pvParam parameter must point to an ANIMATIONINFO structure 
        /// that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(ANIMATIONINFO).
        /// </summary>
        SETANIMATION = 0x0049,

        /// <summary>
        /// Determines whether the font smoothing feature is enabled. This feature uses font antialiasing to make font curves appear smoother 
        /// by painting pixels at different gray levels. 
        /// The pvParam parameter must point to a BOOL variable that receives TRUE if the feature is enabled, or FALSE if it is not.
        /// Windows 95:  This flag is supported only if Windows Plus! is installed. See SPI_GETWINDOWSEXTENSION.
        /// </summary>
        GETFONTSMOOTHING = 0x004A,

        /// <summary>
        /// Enables or disables the font smoothing feature, which uses font antialiasing to make font curves appear smoother 
        /// by painting pixels at different gray levels. 
        /// To enable the feature, set the uiParam parameter to TRUE. To disable the feature, set uiParam to FALSE.
        /// Windows 95:  This flag is supported only if Windows Plus! is installed. See SPI_GETWINDOWSEXTENSION.
        /// </summary>
        SETFONTSMOOTHING = 0x004B,

        /// <summary>
        /// Sets the width, in pixels, of the rectangle used to detect the start of a drag operation. Set uiParam to the new value. 
        /// To retrieve the drag width, call GetSystemMetrics with the SM_CXDRAG flag.
        /// </summary>
        SETDRAGWIDTH = 0x004C,

        /// <summary>
        /// Sets the height, in pixels, of the rectangle used to detect the start of a drag operation. Set uiParam to the new value. 
        /// To retrieve the drag height, call GetSystemMetrics with the SM_CYDRAG flag.
        /// </summary>
        SETDRAGHEIGHT = 0x004D,

        /// <summary>
        /// Used internally; applications should not use this value.
        /// </summary>
        SETHANDHELD = 0x004E,

        /// <summary>
        /// Retrieves the time-out value for the low-power phase of screen saving. The pvParam parameter must point to an integer variable 
        /// that receives the value. This flag is supported for 32-bit applications only.
        /// Windows NT, Windows Me/98:  This flag is supported for 16-bit and 32-bit applications.
        /// Windows 95:  This flag is supported for 16-bit applications only.
        /// </summary>
        GETLOWPOWERTIMEOUT = 0x004F,

        /// <summary>
        /// Retrieves the time-out value for the power-off phase of screen saving. The pvParam parameter must point to an integer variable 
        /// that receives the value. This flag is supported for 32-bit applications only.
        /// Windows NT, Windows Me/98:  This flag is supported for 16-bit and 32-bit applications.
        /// Windows 95:  This flag is supported for 16-bit applications only.
        /// </summary>
        GETPOWEROFFTIMEOUT = 0x0050,

        /// <summary>
        /// Sets the time-out value, in seconds, for the low-power phase of screen saving. The uiParam parameter specifies the new value. 
        /// The pvParam parameter must be null. This flag is supported for 32-bit applications only.
        /// Windows NT, Windows Me/98:  This flag is supported for 16-bit and 32-bit applications.
        /// Windows 95:  This flag is supported for 16-bit applications only.
        /// </summary>
        SETLOWPOWERTIMEOUT = 0x0051,

        /// <summary>
        /// Sets the time-out value, in seconds, for the power-off phase of screen saving. The uiParam parameter specifies the new value. 
        /// The pvParam parameter must be null. This flag is supported for 32-bit applications only.
        /// Windows NT, Windows Me/98:  This flag is supported for 16-bit and 32-bit applications.
        /// Windows 95:  This flag is supported for 16-bit applications only.
        /// </summary>
        SETPOWEROFFTIMEOUT = 0x0052,

        /// <summary>
        /// Determines whether the low-power phase of screen saving is enabled. The pvParam parameter must point to a BOOL variable 
        /// that receives TRUE if enabled, or FALSE if disabled. This flag is supported for 32-bit applications only.
        /// Windows NT, Windows Me/98:  This flag is supported for 16-bit and 32-bit applications.
        /// Windows 95:  This flag is supported for 16-bit applications only.
        /// </summary>
        GETLOWPOWERACTIVE = 0x0053,

        /// <summary>
        /// Determines whether the power-off phase of screen saving is enabled. The pvParam parameter must point to a BOOL variable 
        /// that receives TRUE if enabled, or FALSE if disabled. This flag is supported for 32-bit applications only.
        /// Windows NT, Windows Me/98:  This flag is supported for 16-bit and 32-bit applications.
        /// Windows 95:  This flag is supported for 16-bit applications only.
        /// </summary>
        GETPOWEROFFACTIVE = 0x0054,

        /// <summary>
        /// Activates or deactivates the low-power phase of screen saving. Set uiParam to 1 to activate, or zero to deactivate. 
        /// The pvParam parameter must be null. This flag is supported for 32-bit applications only.
        /// Windows NT, Windows Me/98:  This flag is supported for 16-bit and 32-bit applications.
        /// Windows 95:  This flag is supported for 16-bit applications only.
        /// </summary>
        SETLOWPOWERACTIVE = 0x0055,

        /// <summary>
        /// Activates or deactivates the power-off phase of screen saving. Set uiParam to 1 to activate, or zero to deactivate. 
        /// The pvParam parameter must be null. This flag is supported for 32-bit applications only.
        /// Windows NT, Windows Me/98:  This flag is supported for 16-bit and 32-bit applications.
        /// Windows 95:  This flag is supported for 16-bit applications only.
        /// </summary>
        SETPOWEROFFACTIVE = 0x0056,

        /// <summary>
        /// Reloads the system cursors. Set the uiParam parameter to zero and the pvParam parameter to null.
        /// </summary>
        SETCURSORS = 0x0057,

        /// <summary>
        /// Reloads the system icons. Set the uiParam parameter to zero and the pvParam parameter to null.
        /// </summary>
        SETICONS = 0x0058,

        /// <summary>
        /// Retrieves the input locale identifier for the system default input language. The pvParam parameter must point 
        /// to an HKL variable that receives this value. For more information, see Languages, Locales, and Keyboard Layouts on MSDN.
        /// </summary>
        GETDEFAULTINPUTLANG = 0x0059,

        /// <summary>
        /// Sets the default input language for the system shell and applications. The specified language must be displayable 
        /// using the current system character set. The pvParam parameter must point to an HKL variable that contains 
        /// the input locale identifier for the default language. For more information, see Languages, Locales, and Keyboard Layouts on MSDN.
        /// </summary>
        SETDEFAULTINPUTLANG = 0x005A,

        /// <summary>
        /// Sets the hot key set for switching between input languages. The uiParam and pvParam parameters are not used. 
        /// The value sets the shortcut keys in the keyboard property sheets by reading the registry again. The registry must be set before this flag is used. the path in the registry is \HKEY_CURRENT_USER\keyboard layout\toggle. Valid values are "1" = ALT+SHIFT, "2" = CTRL+SHIFT, and "3" = none.
        /// </summary>
        SETLANGTOGGLE = 0x005B,

        /// <summary>
        /// Windows 95:  Determines whether the Windows extension, Windows Plus!, is installed. Set the uiParam parameter to 1. 
        /// The pvParam parameter is not used. The function returns TRUE if the extension is installed, or FALSE if it is not.
        /// </summary>
        GETWINDOWSEXTENSION = 0x005C,

        /// <summary>
        /// Enables or disables the Mouse Trails feature, which improves the visibility of mouse cursor movements by briefly showing 
        /// a trail of cursors and quickly erasing them. 
        /// To disable the feature, set the uiParam parameter to zero or 1. To enable the feature, set uiParam to a value greater than 1 
        /// to indicate the number of cursors drawn in the trail.
        /// Windows 2000/NT:  This value is not supported.
        /// </summary>
        SETMOUSETRAILS = 0x005D,

        /// <summary>
        /// Determines whether the Mouse Trails feature is enabled. This feature improves the visibility of mouse cursor movements 
        /// by briefly showing a trail of cursors and quickly erasing them. 
        /// The pvParam parameter must point to an integer variable that receives a value. If the value is zero or 1, the feature is disabled. 
        /// If the value is greater than 1, the feature is enabled and the value indicates the number of cursors drawn in the trail. 
        /// The uiParam parameter is not used.
        /// Windows 2000/NT:  This value is not supported.
        /// </summary>
        GETMOUSETRAILS = 0x005E,

        /// <summary>
        /// Windows Me/98:  Used internally; applications should not use this flag.
        /// </summary>
        SETSCREENSAVERRUNNING = 0x0061,

        /// <summary>Same as SPI_SETSCREENSAVERRUNNING.</summary>
        SCREENSAVERRUNNING = SETSCREENSAVERRUNNING,
        //#endif /* WINVER >= 0x0400 */

        /// <summary>
        /// Retrieves information about the FilterKeys accessibility feature. The pvParam parameter must point to a FILTERKEYS structure 
        /// that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(FILTERKEYS).
        /// </summary>
        GETFILTERKEYS = 0x0032,

        /// <summary>
        /// Sets the parameters of the FilterKeys accessibility feature. The pvParam parameter must point to a FILTERKEYS structure 
        /// that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(FILTERKEYS).
        /// </summary>
        SETFILTERKEYS = 0x0033,

        /// <summary>
        /// Retrieves information about the ToggleKeys accessibility feature. The pvParam parameter must point to a TOGGLEKEYS structure 
        /// that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(TOGGLEKEYS).
        /// </summary>
        GETTOGGLEKEYS = 0x0034,

        /// <summary>
        /// Sets the parameters of the ToggleKeys accessibility feature. The pvParam parameter must point to a TOGGLEKEYS structure 
        /// that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(TOGGLEKEYS).
        /// </summary>
        SETTOGGLEKEYS = 0x0035,

        /// <summary>
        /// Retrieves information about the MouseKeys accessibility feature. The pvParam parameter must point to a MOUSEKEYS structure 
        /// that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(MOUSEKEYS).
        /// </summary>
        GETMOUSEKEYS = 0x0036,

        /// <summary>
        /// Sets the parameters of the MouseKeys accessibility feature. The pvParam parameter must point to a MOUSEKEYS structure 
        /// that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(MOUSEKEYS).
        /// </summary>
        SETMOUSEKEYS = 0x0037,

        /// <summary>
        /// Determines whether the Show Sounds accessibility flag is on or off. If it is on, the user requires an application 
        /// to present information visually in situations where it would otherwise present the information only in audible form. 
        /// The pvParam parameter must point to a BOOL variable that receives TRUE if the feature is on, or FALSE if it is off. 
        /// Using this value is equivalent to calling GetSystemMetrics (SM_SHOWSOUNDS). That is the recommended call.
        /// </summary>
        GETSHOWSOUNDS = 0x0038,

        /// <summary>
        /// Sets the parameters of the SoundSentry accessibility feature. The pvParam parameter must point to a SOUNDSENTRY structure 
        /// that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(SOUNDSENTRY).
        /// </summary>
        SETSHOWSOUNDS = 0x0039,

        /// <summary>
        /// Retrieves information about the StickyKeys accessibility feature. The pvParam parameter must point to a STICKYKEYS structure 
        /// that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(STICKYKEYS).
        /// </summary>
        GETSTICKYKEYS = 0x003A,

        /// <summary>
        /// Sets the parameters of the StickyKeys accessibility feature. The pvParam parameter must point to a STICKYKEYS structure 
        /// that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(STICKYKEYS).
        /// </summary>
        SETSTICKYKEYS = 0x003B,

        /// <summary>
        /// Retrieves information about the time-out period associated with the accessibility features. The pvParam parameter must point 
        /// to an ACCESSTIMEOUT structure that receives the information. Set the cbSize member of this structure and the uiParam parameter 
        /// to sizeof(ACCESSTIMEOUT).
        /// </summary>
        GETACCESSTIMEOUT = 0x003C,

        /// <summary>
        /// Sets the time-out period associated with the accessibility features. The pvParam parameter must point to an ACCESSTIMEOUT 
        /// structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(ACCESSTIMEOUT).
        /// </summary>
        SETACCESSTIMEOUT = 0x003D,

        //#if(WINVER >= 0x0400)
        /// <summary>
        /// Windows Me/98/95:  Retrieves information about the SerialKeys accessibility feature. The pvParam parameter must point 
        /// to a SERIALKEYS structure that receives the information. Set the cbSize member of this structure and the uiParam parameter 
        /// to sizeof(SERIALKEYS).
        /// Windows Server 2003, Windows XP/2000/NT:  Not supported. The user controls this feature through the control panel.
        /// </summary>
        GETSERIALKEYS = 0x003E,

        /// <summary>
        /// Windows Me/98/95:  Sets the parameters of the SerialKeys accessibility feature. The pvParam parameter must point 
        /// to a SERIALKEYS structure that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter 
        /// to sizeof(SERIALKEYS). 
        /// Windows Server 2003, Windows XP/2000/NT:  Not supported. The user controls this feature through the control panel.
        /// </summary>
        SETSERIALKEYS = 0x003F,
        //#endif /* WINVER >= 0x0400 */ 

        /// <summary>
        /// Retrieves information about the SoundSentry accessibility feature. The pvParam parameter must point to a SOUNDSENTRY structure 
        /// that receives the information. Set the cbSize member of this structure and the uiParam parameter to sizeof(SOUNDSENTRY).
        /// </summary>
        GETSOUNDSENTRY = 0x0040,

        /// <summary>
        /// Sets the parameters of the SoundSentry accessibility feature. The pvParam parameter must point to a SOUNDSENTRY structure 
        /// that contains the new parameters. Set the cbSize member of this structure and the uiParam parameter to sizeof(SOUNDSENTRY).
        /// </summary>
        SETSOUNDSENTRY = 0x0041,

        //#if(_WIN32_WINNT >= 0x0400)
        /// <summary>
        /// Determines whether the snap-to-default-button feature is enabled. If enabled, the mouse cursor automatically moves 
        /// to the default button, such as OK or Apply, of a dialog box. The pvParam parameter must point to a BOOL variable 
        /// that receives TRUE if the feature is on, or FALSE if it is off. 
        /// Windows 95:  Not supported.
        /// </summary>
        GETSNAPTODEFBUTTON = 0x005F,

        /// <summary>
        /// Enables or disables the snap-to-default-button feature. If enabled, the mouse cursor automatically moves to the default button, 
        /// such as OK or Apply, of a dialog box. Set the uiParam parameter to TRUE to enable the feature, or FALSE to disable it. 
        /// Applications should use the ShowWindow function when displaying a dialog box so the dialog manager can position the mouse cursor. 
        /// Windows 95:  Not supported.
        /// </summary>
        SETSNAPTODEFBUTTON = 0x0060,
        //#endif /* _WIN32_WINNT >= 0x0400 */

        //#if (_WIN32_WINNT >= 0x0400) || (_WIN32_WINDOWS > 0x0400)
        /// <summary>
        /// Retrieves the width, in pixels, of the rectangle within which the mouse pointer has to stay for TrackMouseEvent
        /// to generate a WM_MOUSEHOVER message. The pvParam parameter must point to a UINT variable that receives the width. 
        /// Windows 95:  Not supported.
        /// </summary>
        GETMOUSEHOVERWIDTH = 0x0062,

        /// <summary>
        /// Retrieves the width, in pixels, of the rectangle within which the mouse pointer has to stay for TrackMouseEvent
        /// to generate a WM_MOUSEHOVER message. The pvParam parameter must point to a UINT variable that receives the width. 
        /// Windows 95:  Not supported.
        /// </summary>
        SETMOUSEHOVERWIDTH = 0x0063,

        /// <summary>
        /// Retrieves the height, in pixels, of the rectangle within which the mouse pointer has to stay for TrackMouseEvent 
        /// to generate a WM_MOUSEHOVER message. The pvParam parameter must point to a UINT variable that receives the height. 
        /// Windows 95:  Not supported.
        /// </summary>
        GETMOUSEHOVERHEIGHT = 0x0064,

        /// <summary>
        /// Sets the height, in pixels, of the rectangle within which the mouse pointer has to stay for TrackMouseEvent 
        /// to generate a WM_MOUSEHOVER message. Set the uiParam parameter to the new height.
        /// Windows 95:  Not supported.
        /// </summary>
        SETMOUSEHOVERHEIGHT = 0x0065,

        /// <summary>
        /// Retrieves the time, in milliseconds, that the mouse pointer has to stay in the hover rectangle for TrackMouseEvent 
        /// to generate a WM_MOUSEHOVER message. The pvParam parameter must point to a UINT variable that receives the time. 
        /// Windows 95:  Not supported.
        /// </summary>
        GETMOUSEHOVERTIME = 0x0066,

        /// <summary>
        /// Sets the time, in milliseconds, that the mouse pointer has to stay in the hover rectangle for TrackMouseEvent 
        /// to generate a WM_MOUSEHOVER message. This is used only if you pass HOVER_DEFAULT in the dwHoverTime parameter in the call to TrackMouseEvent. Set the uiParam parameter to the new time. 
        /// Windows 95:  Not supported.
        /// </summary>
        SETMOUSEHOVERTIME = 0x0067,

        /// <summary>
        /// Retrieves the number of lines to scroll when the mouse wheel is rotated. The pvParam parameter must point 
        /// to a UINT variable that receives the number of lines. The default value is 3. 
        /// Windows 95:  Not supported.
        /// </summary>
        GETWHEELSCROLLLINES = 0x0068,

        /// <summary>
        /// Sets the number of lines to scroll when the mouse wheel is rotated. The number of lines is set from the uiParam parameter. 
        /// The number of lines is the suggested number of lines to scroll when the mouse wheel is rolled without using modifier keys. 
        /// If the number is 0, then no scrolling should occur. If the number of lines to scroll is greater than the number of lines viewable, 
        /// and in particular if it is WHEEL_PAGESCROLL (#defined as UINT_MAX), the scroll operation should be interpreted 
        /// as clicking once in the page down or page up regions of the scroll bar.
        /// Windows 95:  Not supported.
        /// </summary>
        SETWHEELSCROLLLINES = 0x0069,

        /// <summary>
        /// Retrieves the time, in milliseconds, that the system waits before displaying a shortcut menu when the mouse cursor is 
        /// over a submenu item. The pvParam parameter must point to a DWORD variable that receives the time of the delay. 
        /// Windows 95:  Not supported.
        /// </summary>
        GETMENUSHOWDELAY = 0x006A,

        /// <summary>
        /// Sets uiParam to the time, in milliseconds, that the system waits before displaying a shortcut menu when the mouse cursor is 
        /// over a submenu item. 
        /// Windows 95:  Not supported.
        /// </summary>
        SETMENUSHOWDELAY = 0x006B,

        /// <summary>
        /// Determines whether the IME status window is visible (on a per-user basis). The pvParam parameter must point to a BOOL variable 
        /// that receives TRUE if the status window is visible, or FALSE if it is not.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETSHOWIMEUI = 0x006E,

        /// <summary>
        /// Sets whether the IME status window is visible or not on a per-user basis. The uiParam parameter specifies TRUE for on or FALSE for off.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETSHOWIMEUI = 0x006F,
        //#endif

        //#if(WINVER >= 0x0500)
        /// <summary>
        /// Retrieves the current mouse speed. The mouse speed determines how far the pointer will move based on the distance the mouse moves. 
        /// The pvParam parameter must point to an integer that receives a value which ranges between 1 (slowest) and 20 (fastest). 
        /// A value of 10 is the default. The value can be set by an end user using the mouse control panel application or 
        /// by an application using SPI_SETMOUSESPEED.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETMOUSESPEED = 0x0070,

        /// <summary>
        /// Sets the current mouse speed. The pvParam parameter is an integer between 1 (slowest) and 20 (fastest). A value of 10 is the default. 
        /// This value is typically set using the mouse control panel application.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETMOUSESPEED = 0x0071,

        /// <summary>
        /// Determines whether a screen saver is currently running on the window station of the calling process. 
        /// The pvParam parameter must point to a BOOL variable that receives TRUE if a screen saver is currently running, or FALSE otherwise.
        /// Note that only the interactive window station, "WinSta0", can have a screen saver running.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETSCREENSAVERRUNNING = 0x0072,

        /// <summary>
        /// Retrieves the full path of the bitmap file for the desktop wallpaper. The pvParam parameter must point to a buffer 
        /// that receives a null-terminated path string. Set the uiParam parameter to the size, in characters, of the pvParam buffer. The returned string will not exceed MAX_PATH characters. If there is no desktop wallpaper, the returned string is empty.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETDESKWALLPAPER = 0x0073,
        //#endif /* WINVER >= 0x0500 */

        //#if(WINVER >= 0x0500)
        /// <summary>
        /// Determines whether active window tracking (activating the window the mouse is on) is on or off. The pvParam parameter must point 
        /// to a BOOL variable that receives TRUE for on, or FALSE for off.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETACTIVEWINDOWTRACKING = 0x1000,

        /// <summary>
        /// Sets active window tracking (activating the window the mouse is on) either on or off. Set pvParam to TRUE for on or FALSE for off.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETACTIVEWINDOWTRACKING = 0x1001,

        /// <summary>
        /// Determines whether the menu animation feature is enabled. This master switch must be on to enable menu animation effects. 
        /// The pvParam parameter must point to a BOOL variable that receives TRUE if animation is enabled and FALSE if it is disabled. 
        /// If animation is enabled, SPI_GETMENUFADE indicates whether menus use fade or slide animation.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETMENUANIMATION = 0x1002,

        /// <summary>
        /// Enables or disables menu animation. This master switch must be on for any menu animation to occur. 
        /// The pvParam parameter is a BOOL variable; set pvParam to TRUE to enable animation and FALSE to disable animation.
        /// If animation is enabled, SPI_GETMENUFADE indicates whether menus use fade or slide animation.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETMENUANIMATION = 0x1003,

        /// <summary>
        /// Determines whether the slide-open effect for combo boxes is enabled. The pvParam parameter must point to a BOOL variable 
        /// that receives TRUE for enabled, or FALSE for disabled.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETCOMBOBOXANIMATION = 0x1004,

        /// <summary>
        /// Enables or disables the slide-open effect for combo boxes. Set the pvParam parameter to TRUE to enable the gradient effect, 
        /// or FALSE to disable it.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETCOMBOBOXANIMATION = 0x1005,

        /// <summary>
        /// Determines whether the smooth-scrolling effect for list boxes is enabled. The pvParam parameter must point to a BOOL variable 
        /// that receives TRUE for enabled, or FALSE for disabled.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETLISTBOXSMOOTHSCROLLING = 0x1006,

        /// <summary>
        /// Enables or disables the smooth-scrolling effect for list boxes. Set the pvParam parameter to TRUE to enable the smooth-scrolling effect,
        /// or FALSE to disable it.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETLISTBOXSMOOTHSCROLLING = 0x1007,

        /// <summary>
        /// Determines whether the gradient effect for window title bars is enabled. The pvParam parameter must point to a BOOL variable 
        /// that receives TRUE for enabled, or FALSE for disabled. For more information about the gradient effect, see the GetSysColor function.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETGRADIENTCAPTIONS = 0x1008,

        /// <summary>
        /// Enables or disables the gradient effect for window title bars. Set the pvParam parameter to TRUE to enable it, or FALSE to disable it. 
        /// The gradient effect is possible only if the system has a color depth of more than 256 colors. For more information about 
        /// the gradient effect, see the GetSysColor function.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETGRADIENTCAPTIONS = 0x1009,

        /// <summary>
        /// Determines whether menu access keys are always underlined. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if menu access keys are always underlined, and FALSE if they are underlined only when the menu is activated by the keyboard.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETKEYBOARDCUES = 0x100A,

        /// <summary>
        /// Sets the underlining of menu access key letters. The pvParam parameter is a BOOL variable. Set pvParam to TRUE to always underline menu 
        /// access keys, or FALSE to underline menu access keys only when the menu is activated from the keyboard.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETKEYBOARDCUES = 0x100B,

        /// <summary>Same as SPI_GETKEYBOARDCUES.</summary>
        GETMENUUNDERLINES = GETKEYBOARDCUES,

        /// <summary>Same as SPI_SETKEYBOARDCUES.</summary>
        SETMENUUNDERLINES = SETKEYBOARDCUES,

        /// <summary>
        /// Determines whether windows activated through active window tracking will be brought to the top. The pvParam parameter must point 
        /// to a BOOL variable that receives TRUE for on, or FALSE for off.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETACTIVEWNDTRKZORDER = 0x100C,

        /// <summary>
        /// Determines whether or not windows activated through active window tracking should be brought to the top. Set pvParam to TRUE 
        /// for on or FALSE for off.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETACTIVEWNDTRKZORDER = 0x100D,

        /// <summary>
        /// Determines whether hot tracking of user-interface elements, such as menu names on menu bars, is enabled. The pvParam parameter 
        /// must point to a BOOL variable that receives TRUE for enabled, or FALSE for disabled. 
        /// Hot tracking means that when the cursor moves over an item, it is highlighted but not selected. You can query this value to decide 
        /// whether to use hot tracking in the user interface of your application.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETHOTTRACKING = 0x100E,

        /// <summary>
        /// Enables or disables hot tracking of user-interface elements such as menu names on menu bars. Set the pvParam parameter to TRUE 
        /// to enable it, or FALSE to disable it.
        /// Hot-tracking means that when the cursor moves over an item, it is highlighted but not selected.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETHOTTRACKING = 0x100F,

        /// <summary>
        /// Determines whether menu fade animation is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// when fade animation is enabled and FALSE when it is disabled. If fade animation is disabled, menus use slide animation. 
        /// This flag is ignored unless menu animation is enabled, which you can do using the SPI_SETMENUANIMATION flag. 
        /// For more information, see AnimateWindow.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETMENUFADE = 0x1012,

        /// <summary>
        /// Enables or disables menu fade animation. Set pvParam to TRUE to enable the menu fade effect or FALSE to disable it. 
        /// If fade animation is disabled, menus use slide animation. he The menu fade effect is possible only if the system 
        /// has a color depth of more than 256 colors. This flag is ignored unless SPI_MENUANIMATION is also set. For more information, 
        /// see AnimateWindow.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETMENUFADE = 0x1013,

        /// <summary>
        /// Determines whether the selection fade effect is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if enabled or FALSE if disabled. 
        /// The selection fade effect causes the menu item selected by the user to remain on the screen briefly while fading out 
        /// after the menu is dismissed.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETSELECTIONFADE = 0x1014,

        /// <summary>
        /// Set pvParam to TRUE to enable the selection fade effect or FALSE to disable it.
        /// The selection fade effect causes the menu item selected by the user to remain on the screen briefly while fading out 
        /// after the menu is dismissed. The selection fade effect is possible only if the system has a color depth of more than 256 colors.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETSELECTIONFADE = 0x1015,

        /// <summary>
        /// Determines whether ToolTip animation is enabled. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if enabled or FALSE if disabled. If ToolTip animation is enabled, SPI_GETTOOLTIPFADE indicates whether ToolTips use fade or slide animation.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETTOOLTIPANIMATION = 0x1016,

        /// <summary>
        /// Set pvParam to TRUE to enable ToolTip animation or FALSE to disable it. If enabled, you can use SPI_SETTOOLTIPFADE 
        /// to specify fade or slide animation.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETTOOLTIPANIMATION = 0x1017,

        /// <summary>
        /// If SPI_SETTOOLTIPANIMATION is enabled, SPI_GETTOOLTIPFADE indicates whether ToolTip animation uses a fade effect or a slide effect.
        ///  The pvParam parameter must point to a BOOL variable that receives TRUE for fade animation or FALSE for slide animation. 
        ///  For more information on slide and fade effects, see AnimateWindow.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETTOOLTIPFADE = 0x1018,

        /// <summary>
        /// If the SPI_SETTOOLTIPANIMATION flag is enabled, use SPI_SETTOOLTIPFADE to indicate whether ToolTip animation uses a fade effect 
        /// or a slide effect. Set pvParam to TRUE for fade animation or FALSE for slide animation. The tooltip fade effect is possible only 
        /// if the system has a color depth of more than 256 colors. For more information on the slide and fade effects, 
        /// see the AnimateWindow function.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETTOOLTIPFADE = 0x1019,

        /// <summary>
        /// Determines whether the cursor has a shadow around it. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if the shadow is enabled, FALSE if it is disabled. This effect appears only if the system has a color depth of more than 256 colors.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETCURSORSHADOW = 0x101A,

        /// <summary>
        /// Enables or disables a shadow around the cursor. The pvParam parameter is a BOOL variable. Set pvParam to TRUE to enable the shadow 
        /// or FALSE to disable the shadow. This effect appears only if the system has a color depth of more than 256 colors.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETCURSORSHADOW = 0x101B,

        //#if(_WIN32_WINNT >= 0x0501)
        /// <summary>
        /// Retrieves the state of the Mouse Sonar feature. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if enabled or FALSE otherwise. For more information, see About Mouse Input on MSDN.
        /// Windows 2000/NT, Windows 98/95:  This value is not supported.
        /// </summary>
        GETMOUSESONAR = 0x101C,

        /// <summary>
        /// Turns the Sonar accessibility feature on or off. This feature briefly shows several concentric circles around the mouse pointer 
        /// when the user presses and releases the CTRL key. The pvParam parameter specifies TRUE for on and FALSE for off. The default is off. 
        /// For more information, see About Mouse Input.
        /// Windows 2000/NT, Windows 98/95:  This value is not supported.
        /// </summary>
        SETMOUSESONAR = 0x101D,

        /// <summary>
        /// Retrieves the state of the Mouse ClickLock feature. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if enabled, or FALSE otherwise. For more information, see About Mouse Input.
        /// Windows 2000/NT, Windows 98/95:  This value is not supported.
        /// </summary>
        GETMOUSECLICKLOCK = 0x101E,

        /// <summary>
        /// Turns the Mouse ClickLock accessibility feature on or off. This feature temporarily locks down the primary mouse button 
        /// when that button is clicked and held down for the time specified by SPI_SETMOUSECLICKLOCKTIME. The uiParam parameter specifies 
        /// TRUE for on, 
        /// or FALSE for off. The default is off. For more information, see Remarks and About Mouse Input on MSDN.
        /// Windows 2000/NT, Windows 98/95:  This value is not supported.
        /// </summary>
        SETMOUSECLICKLOCK = 0x101F,

        /// <summary>
        /// Retrieves the state of the Mouse Vanish feature. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if enabled or FALSE otherwise. For more information, see About Mouse Input on MSDN.
        /// Windows 2000/NT, Windows 98/95:  This value is not supported.
        /// </summary>
        GETMOUSEVANISH = 0x1020,

        /// <summary>
        /// Turns the Vanish feature on or off. This feature hides the mouse pointer when the user types; the pointer reappears 
        /// when the user moves the mouse. The pvParam parameter specifies TRUE for on and FALSE for off. The default is off. 
        /// For more information, see About Mouse Input on MSDN.
        /// Windows 2000/NT, Windows 98/95:  This value is not supported.
        /// </summary>
        SETMOUSEVANISH = 0x1021,

        /// <summary>
        /// Determines whether native User menus have flat menu appearance. The pvParam parameter must point to a BOOL variable 
        /// that returns TRUE if the flat menu appearance is set, or FALSE otherwise.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETFLATMENU = 0x1022,

        /// <summary>
        /// Enables or disables flat menu appearance for native User menus. Set pvParam to TRUE to enable flat menu appearance 
        /// or FALSE to disable it. 
        /// When enabled, the menu bar uses COLOR_MENUBAR for the menubar background, COLOR_MENU for the menu-popup background, COLOR_MENUHILIGHT 
        /// for the fill of the current menu selection, and COLOR_HILIGHT for the outline of the current menu selection. 
        /// If disabled, menus are drawn using the same metrics and colors as in Windows 2000 and earlier.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETFLATMENU = 0x1023,

        /// <summary>
        /// Determines whether the drop shadow effect is enabled. The pvParam parameter must point to a BOOL variable that returns TRUE 
        /// if enabled or FALSE if disabled.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETDROPSHADOW = 0x1024,

        /// <summary>
        /// Enables or disables the drop shadow effect. Set pvParam to TRUE to enable the drop shadow effect or FALSE to disable it. 
        /// You must also have CS_DROPSHADOW in the window class style.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETDROPSHADOW = 0x1025,

        /// <summary>
        /// Retrieves a BOOL indicating whether an application can reset the screensaver's timer by calling the SendInput function 
        /// to simulate keyboard or mouse input. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if the simulated input will be blocked, or FALSE otherwise. 
        /// </summary>
        GETBLOCKSENDINPUTRESETS = 0x1026,

        /// <summary>
        /// Determines whether an application can reset the screensaver's timer by calling the SendInput function to simulate keyboard 
        /// or mouse input. The uiParam parameter specifies TRUE if the screensaver will not be deactivated by simulated input, 
        /// or FALSE if the screensaver will be deactivated by simulated input.
        /// </summary>
        SETBLOCKSENDINPUTRESETS = 0x1027,
        //#endif /* _WIN32_WINNT >= 0x0501 */

        /// <summary>
        /// Determines whether UI effects are enabled or disabled. The pvParam parameter must point to a BOOL variable that receives TRUE 
        /// if all UI effects are enabled, or FALSE if they are disabled.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETUIEFFECTS = 0x103E,

        /// <summary>
        /// Enables or disables UI effects. Set the pvParam parameter to TRUE to enable all UI effects or FALSE to disable all UI effects.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETUIEFFECTS = 0x103F,

        /// <summary>
        /// Retrieves the amount of time following user input, in milliseconds, during which the system will not allow applications 
        /// to force themselves into the foreground. The pvParam parameter must point to a DWORD variable that receives the time.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETFOREGROUNDLOCKTIMEOUT = 0x2000,

        /// <summary>
        /// Sets the amount of time following user input, in milliseconds, during which the system does not allow applications 
        /// to force themselves into the foreground. Set pvParam to the new timeout value.
        /// The calling thread must be able to change the foreground window, otherwise the call fails.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETFOREGROUNDLOCKTIMEOUT = 0x2001,

        /// <summary>
        /// Retrieves the active window tracking delay, in milliseconds. The pvParam parameter must point to a DWORD variable 
        /// that receives the time.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETACTIVEWNDTRKTIMEOUT = 0x2002,

        /// <summary>
        /// Sets the active window tracking delay. Set pvParam to the number of milliseconds to delay before activating the window 
        /// under the mouse pointer.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETACTIVEWNDTRKTIMEOUT = 0x2003,

        /// <summary>
        /// Retrieves the number of times SetForegroundWindow will flash the taskbar button when rejecting a foreground switch request. 
        /// The pvParam parameter must point to a DWORD variable that receives the value.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        GETFOREGROUNDFLASHCOUNT = 0x2004,

        /// <summary>
        /// Sets the number of times SetForegroundWindow will flash the taskbar button when rejecting a foreground switch request. 
        /// Set pvParam to the number of times to flash.
        /// Windows NT, Windows 95:  This value is not supported.
        /// </summary>
        SETFOREGROUNDFLASHCOUNT = 0x2005,

        /// <summary>
        /// Retrieves the caret width in edit controls, in pixels. The pvParam parameter must point to a DWORD that receives this value.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETCARETWIDTH = 0x2006,

        /// <summary>
        /// Sets the caret width in edit controls. Set pvParam to the desired width, in pixels. The default and minimum value is 1.
        /// Windows NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETCARETWIDTH = 0x2007,

        //#if(_WIN32_WINNT >= 0x0501)
        /// <summary>
        /// Retrieves the time delay before the primary mouse button is locked. The pvParam parameter must point to DWORD that receives 
        /// the time delay. This is only enabled if SPI_SETMOUSECLICKLOCK is set to TRUE. For more information, see About Mouse Input on MSDN.
        /// Windows 2000/NT, Windows 98/95:  This value is not supported.
        /// </summary>
        GETMOUSECLICKLOCKTIME = 0x2008,

        /// <summary>
        /// Turns the Mouse ClickLock accessibility feature on or off. This feature temporarily locks down the primary mouse button 
        /// when that button is clicked and held down for the time specified by SPI_SETMOUSECLICKLOCKTIME. The uiParam parameter 
        /// specifies TRUE for on, or FALSE for off. The default is off. For more information, see Remarks and About Mouse Input on MSDN.
        /// Windows 2000/NT, Windows 98/95:  This value is not supported.
        /// </summary>
        SETMOUSECLICKLOCKTIME = 0x2009,

        /// <summary>
        /// Retrieves the type of font smoothing. The pvParam parameter must point to a UINT that receives the information.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETFONTSMOOTHINGTYPE = 0x200A,

        /// <summary>
        /// Sets the font smoothing type. The pvParam parameter points to a UINT that contains either FE_FONTSMOOTHINGSTANDARD, 
        /// if standard anti-aliasing is used, or FE_FONTSMOOTHINGCLEARTYPE, if ClearType is used. The default is FE_FONTSMOOTHINGSTANDARD. 
        /// When using this option, the fWinIni parameter must be set to SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE; otherwise, 
        /// SystemParametersInfo fails.
        /// </summary>
        SETFONTSMOOTHINGTYPE = 0x200B,

        /// <summary>
        /// Retrieves a contrast value that is used in ClearType™ smoothing. The pvParam parameter must point to a UINT 
        /// that receives the information.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETFONTSMOOTHINGCONTRAST = 0x200C,

        /// <summary>
        /// Sets the contrast value used in ClearType smoothing. The pvParam parameter points to a UINT that holds the contrast value. 
        /// Valid contrast values are from 1000 to 2200. The default value is 1400.
        /// When using this option, the fWinIni parameter must be set to SPIF_SENDWININICHANGE | SPIF_UPDATEINIFILE; otherwise, 
        /// SystemParametersInfo fails.
        /// SPI_SETFONTSMOOTHINGTYPE must also be set to FE_FONTSMOOTHINGCLEARTYPE.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETFONTSMOOTHINGCONTRAST = 0x200D,

        /// <summary>
        /// Retrieves the width, in pixels, of the left and right edges of the focus rectangle drawn with DrawFocusRect. 
        /// The pvParam parameter must point to a UINT.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETFOCUSBORDERWIDTH = 0x200E,

        /// <summary>
        /// Sets the height of the left and right edges of the focus rectangle drawn with DrawFocusRect to the value of the pvParam parameter.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETFOCUSBORDERWIDTH = 0x200F,

        /// <summary>
        /// Retrieves the height, in pixels, of the top and bottom edges of the focus rectangle drawn with DrawFocusRect. 
        /// The pvParam parameter must point to a UINT.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        GETFOCUSBORDERHEIGHT = 0x2010,

        /// <summary>
        /// Sets the height of the top and bottom edges of the focus rectangle drawn with DrawFocusRect to the value of the pvParam parameter.
        /// Windows 2000/NT, Windows Me/98/95:  This value is not supported.
        /// </summary>
        SETFOCUSBORDERHEIGHT = 0x2011,

        /// <summary>Not implemented.</summary>
        GETFONTSMOOTHINGORIENTATION = 0x2012,

        /// <summary>Not implemented.</summary>
        SETFONTSMOOTHINGORIENTATION = 0x2013,
    }
    #endregion // SPI

    [Flags]
    public enum SPIF
    {
        None = 0x00,
        /// <summary>Writes the new system-wide parameter setting to the user profile.</summary>
        SPIF_UPDATEINIFILE = 0x01,
        /// <summary>Broadcasts the WM_SETTINGCHANGE message after updating the user profile.</summary>
        SPIF_SENDCHANGE = 0x02,
        /// <summary>Same as SPIF_SENDCHANGE.</summary>
        SPIF_SENDWININICHANGE = 0x02
    }


    /// <summary>Contains information about the placement of a window on the screen.</summary>
    [Serializable, StructLayout(LayoutKind.Sequential)]
    public struct WINDOWPLACEMENT
    {
        /// <summary>
        /// The length of the structure, in bytes. Before calling the GetWindowPlacement or SetWindowPlacement functions, set this member to sizeof(WINDOWPLACEMENT).
        /// <para>GetWindowPlacement and SetWindowPlacement fail if this member is not set correctly.</para>
        /// </summary>
        public int Length;

        /// <summary>
        /// Specifies flags that control the position of the minimized window and the method by which the window is restored.
        /// </summary>
        public int Flags;

        /// <summary>The current show state of the window.</summary>
        public ShowWindowCommands ShowCmd;

        /// <summary>The coordinates of the window's upper-left corner when the window is minimized.</summary>
        public POINT MinPosition;

        /// <summary>The coordinates of the window's upper-left corner when the window is maximized.</summary>
        public POINT MaxPosition;

        /// <summary>The window's coordinates when the window is in the restored position.</summary>
        public RECT NormalPosition;

        /// <summary>Gets the default (empty) value.</summary>
        public static WINDOWPLACEMENT Default { get { return new WINDOWPLACEMENT { Length = Marshal.SizeOf(typeof(WINDOWPLACEMENT)) }; } }
    }

    public enum RegisterDeviceNotificationFlags
    {
        /// <summary>The hRecipient parameter is a window handle.</summary>
        DEVICE_NOTIFY_WINDOW_HANDLE = 0x00000000,
        /// <summary>The hRecipient parameter is a service status handle.</summary>
        DEVICE_NOTIFY_SERVICE_HANDLE = 0x00000001,
        /// <summary>
        /// Notifies the recipient of device interface events for all device interface classes
        /// (The dbcc_classguid member is ignored.)
        /// his value can be used only if the DeviceType member is DBT_DEVTYP_DEVICEINTERFACE
        /// </summary>
        DEVICE_NOTIFY_ALL_INTERFACE_CLASSES = 0x00000004
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DevBroadcastDeviceInterfaceBuffer
    {
        public enum DeviceT
        {
            DBT_DEVTYP_OEM = 0x00000000,
            DBT_DEVTYP_VOLUME = 0x00000002,
            DBT_DEVTYP_PORT = 0x00000003,
            DBT_DEVTYP_DEVICEINTERFACE = 0x00000005,
            DBT_DEVTYP_HANDLE = 0x00000006
        }


        public DevBroadcastDeviceInterfaceBuffer Default { get { return new DevBroadcastDeviceInterfaceBuffer(0); } }

        public int Size;

        public int DeviceType;

        public int Reserved;

        public DevBroadcastDeviceInterfaceBuffer(int DeviceType)
        {
            Size = Marshal.SizeOf(typeof(DevBroadcastDeviceInterfaceBuffer));
            this.DeviceType = DeviceType;
            Reserved = 0;
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct DeviceBroadcastInterface
    {
        public DeviceBroadcastInterface Default { get { return new DeviceBroadcastInterface { Size = Marshal.SizeOf(typeof(DeviceBroadcastInterface)) }; } }

        public int Size;
        public Guid ClassGuid;
        public byte DeviceType;
        public int Reserved;
    }

    public delegate bool EnumThreadDelegate(IntPtr hWnd, IntPtr lParam);

    /// <summary>Тип элемента</summary>
    [Flags, Serializable]
    public enum DFC : uint
    {
        /// <summary>Заголовок</summary>
        DFC_CAPTION = 1,
        /// <summary>Меню</summary>
        DFC_MENU = 2,
        /// <summary>Полоса прокрутки</summary>
        DFC_SCROLL = 3,
        /// <summary>Кнопка</summary>
        DFC_BUTTON = 4,
        DFC_POPUPMENU = 5
    }

    /// <summary>Window handles (HWND) used for hWndInsertAfter</summary>
    public static class InsertAfterEnumHWND
    {
        public static readonly IntPtr
            NoTopMost = new IntPtr(-2),
            TopMost = new IntPtr(-1),
            Top = new IntPtr(0),
            Bottom = new IntPtr(1);
    }

    /// <summary>Стиль элемента</summary>
    [Flags, Serializable]
    public enum DFCS
    {
        //Для заголовков
        /// <summary>Кнопка закрыть</summary>
        DFCS_CAPTIONCLOSE = 0,
        /// <summary>Кнопка свернуть</summary>
        DFCS_CAPTIONMIN = 1,
        /// <summary>Кнопка развернуть</summary>
        DFCS_CAPTIONMAX = 2,
        /// <summary>Кнопка восстановить</summary>  
        DFCS_CAPTIONRESTORE = 3,
        /// <summary>Кнопка помощь (только Window 9x)</summary>
        DFCS_CAPTIONHELP = 4,

        //Для меню
        /// <summary>Стрелка подменю</summary>
        DFCS_MENUARROW = 0,
        /// <summary>Маркер - флажек</summary>
        DFCS_MENUCHECK = 1,
        /// <summary>Маркер</summary>
        DFCS_MENUBULLET = 2,
        /// <summary>Стрелка подменю справа</summary>
        DFCS_MENUARROWRIGHT = 4,

        //Для полос прокрутки
        /// <summary>Кнопка вверх</summary>
        DFCS_SCROLLUP = 0,
        /// <summary>Кнопка вниз</summary>
        DFCS_SCROLLDOWN = 1,
        /// <summary>Кнопка влево</summary>
        DFCS_SCROLLLEFT = 2,
        /// <summary>Кнопка вправо</summary>
        DFCS_SCROLLRIGHT = 3,
        /// <summary>Линейка прокрутки выпадаюшего списка</summary>
        DFCS_SCROLLCOMBOBOX = 5,
        /// <summary>Размерная ручка</summary>
        DFCS_SCROLLSIZEGRIP = 8,
        /// <summary>Размерная ручка справа</summary>
        DFCS_SCROLLSIZEGRIPRIGHT = 0x10,

        //Для кнопок
        /// <summary>Флажок</summary>
        DFCS_BUTTONCHECK = 0,
        /// <summary>Картинка для переключателя</summary>
        DFCS_BUTTONRADIOIMAGE = 1,
        /// <summary>Маска для переключателя</summary>
        DFCS_BUTTONRADIOMASK = 2,
        /// <summary>Переключатель</summary>
        DFCS_BUTTONRADIO = 4,
        /// <summary>Кнопка с тремя состояниями</summary>
        DFCS_BUTTON3STATE = 8,
        /// <summary>Кнопка</summary>
        DFCS_BUTTONPUSH = 0x10,

        DFCS_INACTIVE = 0x100,
        DFCS_PUSHED = 0x200,
        DFCS_CHECKED = 0x400,
        DFCS_TRANSPARENT = 0x800,
        DFCS_HOT = 0x1000,
        DFCS_ADJUSTRECT = 0x2000,
        DFCS_FLAT = 0x4000,
        DFCS_MONO = 0x8000
    }
}
